More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 940 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Adjust_loan | 128839121 | 13 mins ago | IN | 0 ETH | 0.000001031751 | ||||
Close_loan | 128816952 | 12 hrs ago | IN | 0 ETH | 0.000000362102 | ||||
Close_loan | 128812548 | 14 hrs ago | IN | 0 ETH | 0.000000681904 | ||||
Close_loan | 128802210 | 20 hrs ago | IN | 0 ETH | 0.00000081088 | ||||
Close_loan | 128743171 | 2 days ago | IN | 0 ETH | 0.000000733051 | ||||
Adjust_loan | 128738171 | 2 days ago | IN | 0 ETH | 0.00000149136 | ||||
Adjust_loan | 128702103 | 3 days ago | IN | 0 ETH | 0.000000196483 | ||||
Adjust_loan | 128700995 | 3 days ago | IN | 0 ETH | 0.000000914325 | ||||
Adjust_loan | 128682904 | 3 days ago | IN | 0 ETH | 0.000000176474 | ||||
Adjust_loan | 128658130 | 4 days ago | IN | 0 ETH | 0.00000076389 | ||||
Adjust_loan | 128658055 | 4 days ago | IN | 0 ETH | 0.000001290109 | ||||
Set Delegate App... | 128656572 | 4 days ago | IN | 0 ETH | 0.000000094372 | ||||
Close_loan | 128651477 | 4 days ago | IN | 0 ETH | 0.000000646134 | ||||
Adjust_loan | 128651222 | 4 days ago | IN | 0 ETH | 0.000000822559 | ||||
Close_loan | 128651206 | 4 days ago | IN | 0 ETH | 0.000000177635 | ||||
Adjust_loan | 128651199 | 4 days ago | IN | 0 ETH | 0.000001206832 | ||||
Adjust_loan | 128651116 | 4 days ago | IN | 0 ETH | 0.00000088978 | ||||
Adjust_loan | 128650945 | 4 days ago | IN | 0 ETH | 0.00000093455 | ||||
Adjust_loan | 128650919 | 4 days ago | IN | 0 ETH | 0.000000964046 | ||||
Close_loan | 128646202 | 4 days ago | IN | 0 ETH | 0.000000611492 | ||||
Adjust_loan | 128612734 | 5 days ago | IN | 0 ETH | 0.00001610846 | ||||
Adjust_loan | 128611111 | 5 days ago | IN | 0 ETH | 0.000006706276 | ||||
Close_loan | 128601489 | 5 days ago | IN | 0 ETH | 0.000004354611 | ||||
Close_loan | 128601425 | 5 days ago | IN | 0 ETH | 0.000004737099 | ||||
Close_loan | 128595027 | 5 days ago | IN | 0 ETH | 0.000002765391 |
Latest 11 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
126449751 | 55 days ago | Contract Creation | 0 ETH | |||
126449751 | 55 days ago | Contract Creation | 0 ETH | |||
125175383 | 84 days ago | Contract Creation | 0 ETH | |||
125175383 | 84 days ago | Contract Creation | 0 ETH | |||
121876336 | 161 days ago | Contract Creation | 0 ETH | |||
121876336 | 161 days ago | Contract Creation | 0 ETH | |||
121876319 | 161 days ago | Contract Creation | 0 ETH | |||
121876319 | 161 days ago | Contract Creation | 0 ETH | |||
121876298 | 161 days ago | Contract Creation | 0 ETH | |||
121876298 | 161 days ago | Contract Creation | 0 ETH | |||
121875837 | 161 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xfb934020...076909ca8 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
CDP Main Controller
Compiler Version
vyper:0.3.10
Contract Source Code (Vyper language format)
#pragma version 0.3.10 """ @title CDP Main Controller @author Curve.Fi (with edits by defidotmoney) @license Copyright (c) Curve.Fi, 2020-2024 - 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 ): """ @notice Contract constructor @param core `DFMProtocolCore` address. Ownership is inherited from this contract. @param stable Address of the protocol stablecoin. This contract must be given minter privileges within the stablecoin. @param monetary_policies Array of `MonetaryPolicy` contracts to initially set. @param debt_ceiling Initial global debt ceiling """ 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: """ @notice Get the total number of deployed markets """ return len(self.markets) @view @external def get_collateral_count() -> uint256: """ @notice Get the number of unique collaterals used within the system @dev It is possible to deploy multiple markets for a collateral, so this number does not necessarily equal the number of markets. """ return len(self.collaterals) @view @external def get_all_markets() -> DynArray[MarketOperator, 65536]: """ @notice Get a list of all deployed `MarketOperator` contracts """ return self.markets @view @external def get_all_collaterals() -> DynArray[address, 65536]: """ @notice Get a list of collaterals for which a market exists """ return self.collaterals @view @external def get_all_markets_for_collateral(collateral: address) -> DynArray[address, 256]: """ @notice Get a list of all deployed `MarketOperator` contracts that use a given collateral """ 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 get_collateral(market: address) -> address: """ @notice Get collateral token for a market @dev Returns empty(address) if market does not exist @param market Market address @return Address of collateral token """ return self.market_contracts[market].collateral @view @external def get_oracle_price(collateral: address) -> uint256: """ @notice Get the current oracle price for `collateral` @dev Uses the AMM of the first market created for this collateral. Reverts if there is no existing market. @param collateral Address of collateral token @return Oracle price of `collateral` with 1e18 precision """ market: address = self.collateral_markets[collateral][0] return AMM(self.market_contracts[market].amm).price_oracle() @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: """ @notice Get the `MarketOperator` and `AMM` implementation contracts used when deploying a market with the given amplification coefficient. @return (AMM address, MarketOperator address) """ 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 get_close_loan_amounts(account: address, market: address) -> (int256, uint256): """ @notice Get balance information related to closing a loan @param account The account to close the loan for @param market Market of the loan being closed @return Debt balance change for caller * negative value indicates the amount burned to close * positive value indicates a surplus from the AMM after closing Collateral balance received from AMM """ amm: AMM = AMM(self._get_market_contracts_or_revert(market).amm) xy: (uint256, uint256) = amm.get_sum_xy(account) debt: uint256 = MarketOperator(market).debt(account) hook_debt_adjustment: int256 = 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) ) debt = self._uint_plus_int(debt, hook_debt_adjustment) return convert(xy[0], int256) - convert(debt, int256), xy[1] @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) -> (int256, uint256): """ @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 @return Debt balance change for caller * negative value indicates the amount burned to close * positive value indicates a surplus from the AMM after closing Collateral balance received from AMM """ 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) return convert(xy[0], int256) - convert(burn_amount, int256), xy[1] @external @nonreentrant('lock') def liquidate(market: address, target: address, min_x: uint256, frac: uint256 = 10**18) -> (int256, uint256): """ @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 @return Debt balance change for caller * negative value indicates the amount burned to liquidate * positive value indicates a surplus received from the AMM Collateral balance received from AMM """ 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) return convert(xy[0], int256) - convert(debt_amount, int256), xy[1] @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" # deploy with `CREATE2` and include `chain.id` in the salt to ensure unique `MarketOperator` # and `AMM` addresses, even if the controller is deployed at the same address on each chain salt_num: uint256 = (chain.id << 176) + (convert(token, uint256) << 16) + len(self.collateral_markets[token]) market: address = create_minimal_proxy_to(impl.market_operator, salt=keccak256(convert(salt_num, bytes32))) amm: address = create_minimal_proxy_to(impl.amm, salt= keccak256(convert(salt_num << 8, bytes32))) 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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":"get_collateral","inputs":[{"name":"market","type":"address"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_oracle_price","inputs":[{"name":"collateral","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"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":"get_close_loan_amounts","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"}],"outputs":[{"name":"","type":"int256"},{"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":[{"name":"","type":"int256"},{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"liquidate","inputs":[{"name":"market","type":"address"},{"name":"target","type":"address"},{"name":"min_x","type":"uint256"}],"outputs":[{"name":"","type":"int256"},{"name":"","type":"uint256"}]},{"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":[{"name":"","type":"int256"},{"name":"","type":"uint256"}]},{"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"}]}]
Deployed Bytecode
0x60003560e01c60026034820660011b61549c01601e39600051565b6393a39776811861431d573461549757602061550460403960206040f361431d565b63da5892fc811861005a573461549757602061552460403960206040f35b63b12d5460811861431d57602436103417615497576000606052610ed55661431d565b63cd15bf4c811861009957346154975760015460405260206040f35b634f02c420811861431d573461549757620201095460405260206040f361431d565b63b1283e77811861431d5760243610341761549757600435600254811015615497576003015460405260206040f361431d565b6324c1173b8118610121576024361034176154975760043562010003548110156154975762010004015460405260206040f35b632ba0840f811861431d57608436103417615497577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610540526103585661431d565b63822b7b09811861431d57602436103417615497576004358060a01c6154975760405262020005604051602052600052604060002080546060526001810154608052600281015460a0525060606060f361431d565b63762e7b9281186101e8576024361034176154975760043560ff81116154975762020006015460405260206040f35b631ac186a68118610206573461549757620201115460405260206040f35b6356021742811861431d57604436103417615497576004358060a01c615497576040526024358060a01c6154975760605262020110604051602052600052604060002080606051602052600052604060002090505460805260206080f361431d565b63d9049c028118610286573461549757620201065460405260206040f35b63496763ce811861431d57602436103417615497576102a361527c565b60043562020107557fa9c9963960181d6ed0ed8fe32c3d0085f8a7f15be99918300892a20b1c5d7ae660043560e052602060e0a10061431d565b634faf4b4881186102fb573461549757620201075460405260206040f35b63a4639128811861431d5734615497576202010c5460405260206040f361431d565b6331dc3ca8811861033b573461549757620201085460405260206040f35b63aa5ff3c0811861431d5760a43610341761549757608435610540525b6004358060a01c61549757610500526024358060a01c61549757610520526000546002146154975760026000556044351561039457600161039a565b60643515155b61040457600f610560527f44464d3a43204e6f206368616e676500000000000000000000000000000000006105805261056050610560518061058001601f826000031636823750506308c379a061052052602061054052601f19601f61056051011660440161053cfd5b61040c614a5f565b6105005160405261041b614ac7565b6105205160405261042d6105c0614336565b6105c080516105605260208101516105805260408101516105a05250610520516107005260026107205263f9c1d1816105e45260046105005161060452610520516106245260406044610644376080016105e0526105e0602081510180610740828460045afa5050506064356040526104a76106a061496d565b6106a0805161086052602081015161088052506101a06101806101a061070060045afa506104d66106e0614d60565b6106e051606435808201828112600083121861549757905090506105c052610520516381bfcbe7610600526105005161062052604435610640526105c0516106605261054051610680526020610600608461061c6000855af161053e573d600060003e3d6000fd5b60203d10615497576106009050516105e05262020108546040526105e05160605261056a6106206148cf565b6106205161060052610600516202010855606435156106e1576064357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156105b457806105c3565b80600003811461549757806000035b905060008112615497576106205260016064351215610659576202010a546106205180820182811061549757905090506202010a556020615504600039600051639dc29fac61064052336106605261062051610680526020610640604461065c6000855af1610637573d600060003e3d6000fd5b60203d1061549757610640518060011c615497576106a0526106a050506106e1565b61060051604052610668615087565b6202010954610620518082018281106154975790509050620201095560206155046000396000516340c10f1961064052336106605261062051610680526020610640604461065c6000855af16106c3573d600060003e3d6000fd5b60203d1061549757610640518060011c615497576106a0526106a050505b60443515610788576044357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81131561071a5780610729565b80600003811461549757806000035b905060008112615497576106205260016044351215610767573360405261056051606052610580516080526106205160a05261078861518f56610788565b3360405261056051606052610580516080526106205160a052610788615010565b61052051604052610580516060526105a0516080526107a56150f4565b3361050051610520517f79be6dfcb3a3568b21afc806c66bcd67098197716d17923c3189da0c7973f826604435610620526105c051610640526040610620a460036000550061431d565b63e231bff0811861080d5734615497576202010a5460405260206040f35b6334bc68d0811861089057604436103417615497576024356060525b6004358060a01c6154975760405262020004604051602052600052604060002054606051106108605760006080526020608061088e565b6202000460405160205260005260406000206060518154811015615497576001820101905054608052602060805bf35b63c1342574811861431d5760843610341761549757606435610540525b6004358060a01c61549757610500526024358060a01c6154975761052052600054600214615497576002600055670de0b6b3a7640000610540511115610953576013610560527f44464d3a43206672616320746f6f2068696768000000000000000000000000006105805261056050610560518061058001601f826000031636823750506308c379a061052052602061054052601f19601f61056051011660440161053cfd5b610500516040526109656105c0614336565b6105c080516105605260208101516105805260408101516105a052506080366105c0376105005163c134257461064052336106605261052051610680526044356106a052610540516106c0526080610640608461065c6000855af16109cf573d600060003e3d6000fd5b60803d1061549757610640905080516105c05260208101516105e052604081018051610600526020810151610620525050610500516107805260086107a052637e7e3db96106645260043361068452610500516106a452610520516106c4526105e0516106e452608001610660526106606020815101806107c0828460045afa5050506105e051604052610a6461072061486f565b61072080516108e052602081015161090052506101a06101806101a061078060045afa50610a93610760614d60565b61076051610640526105e05160405261064051606052610ab46106606148cf565b610660516105e0526202010a546105e05180820182811061549757905090506202010a5562020108546040526105c051606052610af26106606148cf565b610660516202010855610600516105e05180828118828410021890509050610660526106605115610b7d576020615504600039600051639dc29fac61068052610580516106a052610660516106c0526020610680604461069c6000855af1610b5f573d600060003e3d6000fd5b60203d1061549757610680518060011c615497576106e0526106e050505b610600516105e05111610c06576105e051610600511115610c705760206155046000396000516323b872dd61068052610580516106a052336106c0526105e05161060051036106e0526020610680606461069c6000855af1610be4573d600060003e3d6000fd5b60203d1061549757610680518060011c61549757610700526107005050610c70565b610600516105e05103610680526020615504600039600051639dc29fac6106a052336106c052610680516106e05260206106a060446106bc6000855af1610c52573d600060003e3d6000fd5b60203d10615497576106a0518060011c615497576107005261070050505b6106205115610c9a573360405261056051606052610580516080526106205160a052610c9a61518f565b61050051604052610580516060526105a051608052610cb76150f4565b6105205133610500517f9ef0a399defbe09357ef7431cb1cab06dd5ede64767faa82a286b5cbda5eeaf56106205161068052610600516106a0526105e0516106c0526060610680a4610600518060ff1c615497576105e0518060ff1c615497578082038281136000831218615497579050905061068052610620516106a05260406106806003600055f361431d565b631930e825811861431d57604436103417615497576004358060a01c615497576040526024358060a01c615497576060526202010b604051602052600052604060002080606051602052600052604060002090505460805260206080f361431d565b63d2c642f28118610dc65734615497576202010d5460405260206040f35b637027745e811861431d57602436103417615497576004358060a01c6154975760405262020004604051602052600052604060002080541561549757600060018201019050546060526020620200056060516020526000526040600020600181019050546386fc88d3608052602060806004609c845afa610e4c573d600060003e3d6000fd5b60203d106154975760809050f361431d565b638da5cb5b8118610eb957346154975760206020615524600039600051638da5cb5b604052602060406004605c845afa610e9d573d600060003e3d6000fd5b60203d10615497576040518060a01c6154975760805260809050f35b631539838f8118610f5857604436103417615497576024356060525b6004358060a01c615497576040526202000460405160205260005260406000205460605110610f0c57600060805260206080610f56565b62020004604051602052600052604060002060605181548110156154975760018201019050546080526202000560805160205260005260406000206001810190505460a052602060a05bf35b63c0c1fe5f811861431d57604436103417615497576004358060a01c6154975760e0526024358060011c6154975761010052610f9261527c565b6001546101205260e051610120511861100b576019610140527f44464d3a4320726567756c61746f7220756e6368616e676564000000000000006101605261014050610140518061016001601f826000031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b610100511561125d576000610140526000612160526101205163a788461461418052614080614180600461419c845afa61104a573d600060003e3d6000fd5b60803d1061549757614180516141800161010081511161549757805160008161010081116154975780156110a057905b8060051b6020850101518060a01c615497578160051b618240015260010181811861107a575b5050806182205250506141a0516141800161010081511161549757805160208160051b018061a240828560045afa505050506182209050805160208160051b0180610140828560045afa5050506120208101805160208160051b0180612160828560045afa5050505050600061014051610100811161549757801561117357905b8060051b610160015161418052614180516312898b1b6141a05260e0516141c052803b156154975760006141a060246141bc6000855af1611167573d600060003e3d6000fd5b50600101818118611121575b505060e05163eca6a2f6614180526040806141a052806141a0016000610140518083528060051b60008261010081116154975780156111cc57905b8060051b61016001518160051b6020880101526001018181186111ae575b50508201602001915050905081019050806141c052806141a0016000612160518083528060051b600082610100811161549757801561122557905b8060051b61218001518160051b602088010152600101818118611207575b50508201602001915050905081015050803b1561549757600061418061408461419c6000855af161125b573d600060003e3d6000fd5b505b60e0516001557f7e9723534c62b7bad673d3c8d3f03b638fb6c464fe3bf0636db4e7986ec7dce860e0516101405261010051610160526040610140a10061431d565b6356997a62811861431d57346154975760025460405260206040f361431d565b6363cd5a00811460033611161561431d573461549757620100035460405260206040f361431d565b637a520daa81186113505734615497576020806040528060400160006002548083528060051b60008262010000811161549757801561133c57905b80600301548160051b602088010152600101818118611322575b505082016020019150509050810190506040f35b631339051e811861431d57604436103417615497576004358060a01c61549757610500526024358060a01c6154975761052052600054600214615497576002600055610500516040526113a1614ac7565b610520516040526113b36105a0614336565b6105a0805161054052602081015161056052604081015161058052506080366105a0376105205163656c80956106205261050051610640526080610620602461063c6000855af1611409573d600060003e3d6000fd5b60803d1061549757610620905080516105a05260208101516105c0526040810180516105e052602081015161060052505061052051610740526004610760526390ce0765610644526004610500516106645261052051610684526105c0516106a45260600161064052610640602081510180610780828460045afa5050506105c0516040526114996106e061486f565b6106e080516108a05260208101516108c052506101a06101806101a061074060045afa506114c8610720614d60565b61072051610620526105c051604052610620516060526114e96106406148cf565b610640516105c0526202010a546105c05180820182811061549757905090506202010a5562020108546040526105a0516060526115276106406148cf565b6106405162020108556105e0511561159e5760206155046000396000516323b872dd61064052610560516106605233610680526105e0516106a0526020610640606461065c6000855af1611580573d600060003e3d6000fd5b60203d1061549757610640518060011c615497576106c0526106c050505b6020615504600039600051639dc29fac6106405233610660526105c051610680526020610640604461065c6000855af16115dd573d600060003e3d6000fd5b60203d1061549757610640518060011c615497576106a0526106a050506106005115611624573360405261054051606052610560516080526106005160a05261162461518f565b6105205160405261056051606052610580516080526116416150f4565b3361050051610520517fabba776d3d0b8a6980d7277a9d4c2b2d7d9ce50e6d0deac46dd8a52437869ed961060051610640526105e051610660526105c051610680526060610640a46105e0518060ff1c615497576105c0518060ff1c615497578082038281136000831218615497579050905061064052610600516106605260406106406003600055f361431d565b638c3be907811861173d57346154975760208060405280604001600062010003548083528060051b60008262010000811161549757801561172957905b806201000401548160051b60208801015260010181811861170d575b505082016020019150509050810190506040f35b630b59dfaf811861431d57606436103417615497576004358060a01c6154975760a0526024358060a01c6154975760c05260a051156117845760a051604052611784615206565b6202010f60a05160205260005260406000205460e05260006005905b806101005260e0516101005118611815576012610120527f44464d3a4320556e6b6e6f776e20686f6f6b00000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6202010f60a05160205260005260406000206101005181548110156154975760018201019050546101205260c05161012051604052611855610140614323565b61014051186118e6576004610120516040526118726101606143eb565b6101605118156118f157601e610180527f44464d3a4320486f6f6b20646f6573206e6f7420747261636b206465627400006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd6118f1565b6001018181186117a0575b50506020615504600039600051639dc29fac610100523361012052604435610140526020610100604461011c6000855af1611931573d600060003e3d6000fd5b60203d1061549757610100518060011c615497576101605261016050506202011060a05160205260005260406000208060c05160205260005260406000209050805460443580820182811061549757905090508155506202011154604435808201828110615497579050905062020111556202010a5460443580820182811061549757905090506202010a550061431d565b633a92fa8d811861431d57602436103417615497576004358060a01c6154975760405260208060605262020004604051602052600052604060002081606001600082548083528060051b6000826101008111615497578015611a3d57905b806001880101548160051b602088010152600101818118611a21575b5050820160200191505090509050810190506060f361431d565b63e9d4fa128118611a7657602436103417615497576000606052610829565b63c3c854b6811861431d57604436103417615497576004358060a01c615497576040526024358060011c615497576060526060516202010b336020526000526040600020806040516020526000526040600020905055604051337fe259956d1d8c3e1bf78e7ed5737e2520a196a6e9e4b46474a73c00db884dbb5c60605160805260206080a30061431d565b636b35340a8118611b4157602436103417615497576004358060a01c615497576040526202000560405160205260005260406000205460605260206060f35b63e39001ce811861431d57604436103417615497576004358060a01c61549757610180526024358060a01c615497576101a052611b7c61527c565b6101805115611b945761018051604052611b94615206565b6202010f610180516020526000526040600020546101c05260006005905b806101e0526101c0516101e05118611c2a576012610200527f44464d3a4320556e6b6e6f776e20686f6f6b00000000000000000000000000006102205261020050610200518061022001601f826000031636823750506308c379a06101c05260206101e052601f19601f6102005101166044016101dcfd5b6101a0516202010f6101805160205260005260406000206101e0518154811015615497576001820101905054604052611c64610200614323565b6102005114611c7257611cee565b6202010f61018051602052600052604060002060018154801561549757038082558060018301019050905054610200526101c051600181038181116154975790506101e0511015611cf957610200516202010f6101805160205260005260406000206101e0518154811015615497576001820101905055611cf9565b600101818118611bb2575b505062020110610180516020526000526040600020806101a05160205260005260406000209050546101e0526101e05115611d7d57610180516080526101a05160a0526101e0518060ff1c615497577f800000000000000000000000000000000000000000000000000000000000000081146154975760000360c052611d7d614bbb565b6101a051610180517fd2ba1addacfcbcbc23a57b995978f1a0ef460e30f66abcadb6c70cc5c4154bd66101e051610200526020610200a30061431d565b632538c315811861431d57606436103417615497576004358060a01c61549757604052620201075460605262020108546040516359e7137f60a052602060a0600460bc845afa611e0f573d600060003e3d6000fd5b60203d106154975760a0905051808201828110615497579050905060805260605160805110611e4657600060a052602060a0611eb5565b606051608051808203828111615497579050905060a052604051639a49719660e0526040602461010037602060e0604460fc845afa611e8a573d600060003e3d6000fd5b60203d106154975760e090505160c05260a05160c0518082811882841002189050905060e052602060e05bf361431d565b63d3a76351811861431d57602436103417615497576202010e6004356020526000526040600020805460405260018101546060525060406040f361431d565b63248fed2b81186120cc57602436103417615497576004358060a01c615497576060526202010f6060516020526000526040600020805460208160051b01600081601f0160051c60058111615497578015611f6857905b808501548160051b60800152600101818118611f51575b505050505060006101205260006080516004811161549757801561206057905b8060051b60a001516104405260c0366104603761044051604052611fad610520614323565b61052051610460526007610440511660011c6104805260006004905b8061052052600861044051610520511c1615611ff657600161052051600381116154975760051b6104a001525b600101818118611fc957505061012051600381116154975760c0810261014001610460518152610480516020820152604081016104a05181526104c05160208201526104e05160408201526105005160608201525050600181016101205250600101818118611f88575b505060208061044052806104400160006101205180835260c08102600082600481116154975780156120b757905b60c081026101400160c08202602088010160c08160c08460045afa50505060010181811861208e575b50508201602001915050905081019050610440f35b635f88653b811861431d5761012436103417615497576004358060a01c6154975760e0526084358060a01c615497576101005261210761527c565b67016345785d8a0000604435111561217d576012610120527f44464d3a432046656520746f6f206869676800000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b620f424060443510156121ee576011610120527f44464d3a432046656520746f6f206c6f770000000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b670de0b6b3a76400006064351115612264576018610120527f44464d3a432041646d696e2066656520746f6f206869676800000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b662386f26fc1000060e43510156122d957601a610120527f44464d3a43206c697120646973636f756e7420746f6f206c6f770000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6706f05b59d3b2000060c435111561234f57601c610120527f44464d3a43204c6f616e20646973636f756e7420746f6f2068696768000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60e43560c435116123be576020610120527f44464d3a43206c6f616e20646973636f756e743c6c697120646973636f756e746101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b620201065460a4351061242f576014610120527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6101005163a035b1fe610140526020610140600461015c845afa612458573d600060003e3d6000fd5b60203d106154975761014090505161012052610120516124d857600c610140527f44464d3a432070203d3d203000000000000000000000000000000000000000006101605261014050610140518061016001601f826000031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b610120516101005163ceb7f759610140526020610140600461015c6000855af1612507573d600060003e3d6000fd5b60203d10615497576101409050511815612581576012610180527f44464d3a43207020213d2070726963655f7700000000000000000000000000006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd5b6202010e6024356020526000526040600020805461014052600181015461016052506101405161261157601d610180527f44464d3a43204e6f20696d706c656d656e746174696f6e20666f7220410000006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd5b4660b01b60e05160101b80820182811061549757905090506202000460e0516020526000526040600020548082018281106154975790509050610180527f602d3d8160093d39f3363d3d373d3d3d363d73000000000000000000000000006101c0526101605160601b6101d3527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006101e75261018051600052602060002060366101c06000f58015615497576101a0527f602d3d8160093d39f3363d3d373d3d3d363d73000000000000000000000000006101e0526101405160601b6101f3527f5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000610207526101805160081b600052602060002060366101e06000f58015615497576101c0526101a05163d13f90b46101e0526101c0516102005260e05161022052610104356102405260c4356102605260e43561028052803b156154975760006101e060a46101fc6000855af161278e573d600060003e3d6000fd5b506101c05163728cdbca6101e0526101a05161020052610100516102205260e0516102405261012051610260526040604461028037803b156154975760006101e060c46101fc6000855af16127e8573d600060003e3d6000fd5b5060025461ffff8111615497576101a051816003015560018101600255506202000460e05160205260005260406000205461284057620100035461ffff81116154975760e05181620100040155600181016201000355505b6202000460e0516020526000526040600020805460ff8111615497576101a051816001840101556001810182555050620200056101a051602052600052604060002060e05181556101c051600182015560a43560028201555060e0517f11bde9719002acc56e38889ee650bb993138c9e08678d8ba4ddd743825e00d416101a0516101e0526101c0516102005260a4356102205260606101e0a26101a0516101e0526101c0516102005260406101e0f361431d565b632543eb32811861431d57602436103417615497576004358060a01c6154975760405262020005604051602052600052604060002080546060526001810154608052600281015460a0525060605161295557600060c052602060c061296e565b60a05160ff81116154975762020006015460c052602060c05bf361431d565b6375d2ed08811861431d57346154975760015460405260405161299f576000606052602060606129d3565b602060405163305b4d6c606052602060606004607c845afa6129c6573d600060003e3d6000fd5b60203d1061549757606090505bf361431d565b6369ab47b88118612a3057346154975762020108546202010a548082018281106154975790509050620201095480820382811161549757905090506202011154808203828111615497579050905060405260206040f35b635da5f18c811861431d57602436103417615497576004358060011c615497576101605261016051604052612a6361532a565b610160516202010d557f2b5d179d82230ba43503598d00077c0cc165d285bbdf1e763ee4584b9e49561b3361018052610160516101a0526040610180a10061431d565b635b7aaef1811861431d57604436103417615497576004358060a01c615497576104a0526024358060a01c615497576104c0526104c051604052612aeb610500614336565b610500602081019050516104e0526104e05163544fb5c1610540526104a051610560526040610540602461055c845afa612b2a573d600060003e3d6000fd5b60403d10615497576105409050805161050052602081015161052052506104c051639b6c56ec610560526104a051610580526020610560602461057c845afa612b78573d600060003e3d6000fd5b60203d1061549757610560905051610540526104c0516106805260046106a052631baf02036105845260046104a0516105a4526104c0516105c452610540516105e452606001610580526105806020815101806106c0828460045afa50505061054051604052612be961062061486f565b61062080516107e052602081015161080052506101a06101006101a061068060045afa50612c186106606144e4565b61066051610560526105405160405261056051606052612c396105806148cf565b6105805161054052610500518060ff1c61549757610540518060ff1c615497578082038281136000831218615497579050905061058052610520516105a0526040610580f361431d565b632f4b9e4b811861431d57608436103417615497576004358060a01c615497576104a0526024358060a01c615497576104c05260206104c0516106005260016106205263d0ab1c8a6104e45260046104a051610504526104c0516105245260406044610544376080016104e0526104e0602081510180610640828460045afa505050606435604052612d166105a061486f565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa50612d456105e06144e4565b6105e0f361431d565b6305d9d3a2811861431d57608436103417615497576004358060a01c615497576104a0526024358060a01c615497576104c05260206104c05161060052600261062052632406a3506104e45260046104a051610504526104c0516105245260406044610544376080016104e0526104e0602081510180610640828460045afa505050606435604052612de16105a061496d565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa50612e106105e06144e4565b6105e0f361431d565b635af8e5fc8118612f2457604436103417615497576004358060a01c615497576104a0526024358060a01c615497576104c0526104c051639b6c56ec610500526104a051610520526020610500602461051c845afa612e7d573d600060003e3d6000fd5b60203d10615497576105009050516104e05260206104c05161060052600461062052631baf02036105045260046104a051610524526104c051610544526104e0516105645260600161050052610500602081510180610640828460045afa5050506104e051604052612ef06105a061486f565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa50612f1f6105e06144e4565b6105e0f35b63e6932ac8811861431d57604436103417615497576004358060a01c6154975761010052612f5061527c565b61010051604052612f5f615206565b620201065460243510612fd0576014610120527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b602435620200056101005160205260005260406000206002810190505561010051604052620200056101005160205260005260406000206001810190505460605260243560805261301f6150f4565b602435610100517fe2b88e5e080a641a4620ca23c04dcb08bf9cc02097b43e0507d510e1262970a96000610120a30061431d565b63166dabef811861317557606436103417615497576004358060a01c615497576104a0526024358060a01c615497576104c0526044358060a01c615497576104e0526104c051639b6c56ec610520526104e051610540526020610520602461053c845afa6130c6573d600060003e3d6000fd5b60203d10615497576105209050516105005260206104c0516106405260086106605263f4a589746105245260046104a051610544526104c051610564526104e05161058452610500516105a45260800161052052610520602081510180610680828460045afa505050610500516040526131416105e061486f565b6105e080516107a05260208101516107c052506101a06101006101a061064060045afa506131706106206144e4565b610620f35b6326c01303811861431d5760643610341761549757670de0b6b3a7640000610540526108ad5661431d565b638930995f811861431d5760a436103417615497576004358060a01c61549757610500526024358060a01c6154975761052052600054600214615497576002600055604435156131f45760643515156131f7565b60005b613261576014610540527f44464d3a43203020636f6c6c206f7220646562740000000000000000000000006105605261054050610540518061056001601f826000031636823750506308c379a061050052602061052052601f19601f61054051011660440161051cfd5b613269614a5f565b61050051604052613278614ac7565b6105205160405261328a6105a0614336565b6105a080516105405260208101516105605260408101516105805250610520516106e052600161070052632f7e21a46105c4526004610500516105e452610520516106045260406044610624376080016105c0526105c0602081510180610720828460045afa50505060643560405261330461068061486f565b610680805161084052602081015161086052506101a06101806101a06106e060045afa506133336106c0614d60565b6106c0516105a0526064356040526105a0516060526133536105e06148cf565b6105e0516105c05233604052610540516060526105605160805260443560a05261337b615010565b6105205163d9a39df8610600526105005161062052604435610640526105c05161066052608435610680526020610600608461061c6000855af16133c4573d600060003e3d6000fd5b60203d10615497576106009050516105e05262020108546105e05180820182811061549757905090506106005261060051604052613400615087565b61060051620201085562020109546064358082018281106154975790509050620201095560206155046000396000516340c10f19610620523361064052606435610660526020610620604461063c6000855af1613462573d600060003e3d6000fd5b60203d1061549757610620518060011c6154975761068052610680505061052051604052610560516060526105805160805261349c6150f4565b3361050051610520517fbf2742c8e657897c9f047c065e83679fdea6e8bf1a460402c3c922f800b74bf1604435610620526105c051610640526040610620a460036000550061431d565b636280c9ab811861431d576044361034176154975760043560040160ff81351161549757803560008160ff811161549757801561354557905b8060051b6020850101358060a01c615497578160051b610180015260010181811861351f575b505080610160525050600054600214615497576002600055613565614a5f565b602061552460003960005163b3f00674612180526020612180600461219c845afa613595573d600060003e3d6000fd5b60203d1061549757612180518060a01c615497576121c0526121c090505161216052614000366121803760006101605160ff81116154975780156137a357905b8060051b610180015161618052616180516040526135f4616200614336565b61620080516161a05260208101516161c05260408101516161e052506060366162003761618051631e0cfcef616260526060616260600461627c6000855af1613642573d600060003e3d6000fd5b60603d10615497576162609050805161620052602081018051616220526020810151616240525050612180516162005180820182811061549757905090506121805261622051156136f55760206155046000396000516323b872dd616260526161c05161628052612160516162a052616220516162c0526020616260606461627c6000855af16136d7573d600060003e3d6000fd5b60203d1061549757616260518060011c615497576162e0526162e050505b616240511561372257612160516040526161a0516060526161c0516080526162405160a05261372261518f565b616180517f04dd27d55b92d68e556c87c41371d3c5ff554a0abd8ecb5cfa8ac7f917c94f3e616240516162605261622051616280526040616260a26161c0516121a05160fe81116154975760051b6121c001526161e0516121a05160fe81116154975760051b6141a0015260016121a051016121a0526001018181186135d5575b505062020108546121805180820182811061549757905090506161805261618051620201085560006161a05262020109546161c0526202010a546161e052616180516161e051808201828110615497579050905062020111548082038281116154975790509050616200526161c051616200511115613892576162005162020109556161c05161620051036161a05260206155046000396000516340c10f196162205261216051616240526161a051616260526020616220604461623c6000855af1613874573d600060003e3d6000fd5b60203d1061549757616220518060011c615497576162805261628050505b60006121a05260006101605160ff811161549757801561390e57905b8060051b610180015161622052616220516040526121a05160fe81116154975760051b6121c001516060526121a05160fe81116154975760051b6141a001516080526138f86150f4565b60016121a051016121a0526001018181186138ae575b50507f1ac56d7e866e3f5ea9aa92aa11758ead39a0a5f013f3fefb0f47cb9d008edd276161c051616220526161e0516162405261618051616260526161a051616280526080616220a160206161a06003600055f361431d565b63a8d706ed811861431d57606436103417615497576024358060a01c6154975760e0526044358060a01c61549757610100526139a161527c565b600260043510156139b35760006139bc565b61271060043511155b613a24576016610120527f44464d3a432041206f75747369646520626f756e6473000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60e0516101005118613aa1576101005115613c6a57601e610120527f44464d3a43206d61746368696e6720696d706c656d656e746174696f6e7300006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd613c6a565b6101005115613ab45760e0511515613ab7565b60005b613b1f57601a610120527f44464d3a4320656d70747920696d706c656d656e746174696f6e0000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60043560e05163f446c1d0610120526020610120600461013c845afa613b4a573d600060003e3d6000fd5b60203d10615497576101209050511815613bc4576018610160527f44464d3a4320696e636f7272656374206d61726b6574204100000000000000006101805261016050610160518061018001601f826000031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6004356101005163f446c1d0610120526020610120600461013c845afa613bf0573d600060003e3d6000fd5b60203d10615497576101209050511815613c6a576015610160527f44464d3a4320696e636f727265637420616d6d204100000000000000000000006101805261016050610160518061018001601f826000031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6202010e600435602052600052604060002061010051815560e0516001820155506004357fb55605b8d8e835ca6641329db445749b15ad50629b4ee079e7c8e88ea186a426610100516101205260e051610140526040610120a20061431d565b6332edb110811861431d57604436103417615497576004358060a01c6154975760e0526024358060a01c6154975761010052613d0461527c565b60e05115613d1a5760e051604052613d1a615206565b6202010f60e0516020526000526040600020805460208160051b01600081601f0160051c60058111615497578015613d6657905b808501548160051b6101200152600101818118613d4e575b50505050506003610120511115613ddd5760206101c0527f44464d3a43204d6178696d756d20686f6f6b20636f756e7420726561636865646101e0526101c0506101c051806101e001601f826000031636823750506308c379a06101805260206101a052601f19601f6101c051011660440161019cfd5b60006101205160048111615497578015613e9057905b8060051b61014001516101c052610100516101c051604052613e166101e0614323565b6101e05118613e85576018610200527f44464d3a4320486f6f6b20616c726561647920616464656400000000000000006102205261020050610200518061022001601f826000031636823750506308c379a06101c05260206101e052601f19601f6102005101166044016101dcfd5b600101818118613df3575b5050610100516375fec5946102605260a0610260600461027c845afa613ebb573d600060003e3d6000fd5b60a03d10615497576102605161032052610280518060011c61549757610340526102a0518060011c61549757610360526102c0518060011c61549757610380526102e0518060011c615497576103a052610320905080516101c0526020810180516101e052602081015161020052604081015161022052606081015161024052505060026101c0511115613faf576017610260527f44464d3a4320496e76616c696420686f6f6b20747970650000000000000000006102805261026050610260518061028001601f826000031636823750506308c379a061022052602061024052601f19601f61026051011660440161023cfd5b60016101c0511b6102605260006004905b806102805261028051600381116154975760051b6101e00151156140095761026051600161028051600381018181106154975790501b8082018281106154975790509050610260525b600101818118613fc05750506102605160031c61408657601b610280527f44464d3a43204e6f2061637469766520686f6f6b20706f696e747300000000006102a0526102805061028051806102a001601f826000031636823750506308c379a061024052602061026052601f19601f61028051011660440161025cfd5b610260516101005160601b8082018281106154975790509050610260526202010f60e051602052600052604060002080546003811161549757610260518160018401015560018101825550506101005160e0517f87e627cd8c8921af9587fe2e6d32b3cdaa8d64ede0faf1f3b5b67920e03d33406101c051610280526101e0516102a052610200516102c052610220516102e052610240516103005260a0610280a30061431d565b633e100c7e811861431d57602436103417615497576004358060a01c6154975760e05261415961527c565b62020106546101005260e0516101005160ff81116154975762020006015561010051600181018181106154975790506202010655610100517fc52c1bf04d9533f4ddbbb056f87ebeb235891134e87667bf3ff3327ce15886e860e051610120526020610120a20061431d565b63e1eacc8f811861431d57604436103417615497576004358060a01c6154975760e0526141f061527c565b620201065460243510614260576014610100527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101205261010050610100518061012001601f826000031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b60e05160243560ff8111615497576202000601556024357f360fb1b952a743afe4c3396fc3229723a4ebd3cb2a3cefa111bb00bb0ff7589860e051610100526020610100a20061431d565b63f28699fa811861431d57602436103417615497576004358060011c6154975761016052610160516040526142de61532a565b610160516202010c557ff8d26d1a3a211bb38503963aa0898e2a241f291063df5c514d4ed06ae14b97ee3361018052610160516101a0526040610180a1005b60006000fd5b60405160601c8060a01c61549757815250565b62020005604051602052600052604060002080546060526001810154608052600281015460a052506060516143c257601460c0527f44464d3a4320496e76616c6964206d61726b657400000000000000000000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b6060518152608051602082015260a051604082015250565b60605160031b604051161515815250565b6007604051168060031c61549757815250565b606051604051126144155760805160405113614418565b60015b156144e25760a05161448557601e60c0527f44464d3a4320486f6f6b2063617573656420696e76616c69642064656274000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd6144e2565b601c60c0527f44464d3a4320686f6f6b2073756d206f7574206f6620626f756e64730000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b565b60006102a052610100516102e05260006103005260006002905b8060051b6102e001516102c0526202010f6102c0516020526000526040600020805460208160051b01600081601f0160051c6005811161549757801561455857905b808501548160051b6103200152600101818118614540575b50505050506103205161456a5761482f565b6000610320516004811161549757801561482c57905b8060051b61034001516103c0526103c051604052610120516060526145a66103e06143da565b6103e0516145b357614821565b6103c0516040526145c5610400614323565b610400516103e0526103e0515a610140506020610440610140516101608585fa905090506145f8573d600060003e3d6000fd5b3d602081183d6020100218610420526104206020810151815160200360031b1d9050610400526104005161462b57614821565b6103c05160405261463d6104406143eb565b6104405161042052600161042051186146b657601d610440527f44464d3a4320486f6f6b2063616e6e6f742061646a75737420646562740000006104605261044050610440518061046001601f826000031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b600261042051186146e55761040051604052600060605261028051608052600060a0526148016143fe56614801565b610400516040526102605160605261028051608052600060a0526147076143fe565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610400511361480157620201106102c0516020526000526040600020806103e051602052600052604060002090505461044052610400517f80000000000000000000000000000000000000000000000000000000000000008114615497576000036000811261549757610440511015614801576019610460527f44464d3a4320486f6f6b206465627420756e646572666c6f77000000000000006104805261046050610460518061048001601f826000031636823750506308c379a061042052602061044052601f19601f61046051011660440161043cfd5b6102a05161040051808201828112600083121861549757905090506102a0525b600101818118614580575b50505b6001018181186144fe5750506102a05115614866576102a0516040526102605160605261028051608052600160a0526148666143fe565b6102a051815250565b6040518060ff1c615497577f800000000000000000000000000000000000000000000000000000000000000081146154975760000381527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602082015250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6060511315614921576040516060516000811261549757808201828110615497579050905081525061496b5661496b565b6040516060517f8000000000000000000000000000000000000000000000000000000000000000811461549757600003600081126154975780820382811161549757905090508152505b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604051136149f1577f800000000000000000000000000000000000000000000000000000000000000081526040517f8000000000000000000000000000000000000000000000000000000000000000811461549757600003602082015250614a5d565b600160405112614a56576040517f800000000000000000000000000000000000000000000000000000000000000081146154975760000381527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602082015250614a5d565b6040368237505b565b6202010d54614ac55760206040527f44464d3a432050726f746f636f6c2070617573652c20636c6f7365206f6e6c7960605260405060405180606001601f826000031636823750506308c379a06000526020602052601f19601f6040510116604401601cfd5b565b6040513314614bb9576202010c54614b365760196060527f44464d3a432044656c65676174696f6e2064697361626c65640000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6202010b604051602052600052604060002080336020526000526040600020905054614bb957601b6060527f44464d3a432044656c6567617465206e6f7420617070726f766564000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b6202011060805160205260005260406000208060a051602052600052604060002090505460e0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60c05113614cac5760c0517f8000000000000000000000000000000000000000000000000000000000000000811461549757600003600081126154975760e0511015614cac576019610100527f44464d3a4320486f6f6b206465627420756e646572666c6f77000000000000006101205261010050610100518061012001601f826000031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b60e05160405260c051606052614cc36101006148cf565b6101005160e052620201115460405260c051606052614ce36101206148cf565b610120516101005260e0516202011060805160205260005260406000208060a051602052600052604060002090505561010051620201115560a0516080517fce64682be365129d68e82326ad253f548f1f36f36772ea07298122b16c4fbdb260c0516101205260e0516101405261010051610160526060610120a3565b600061032052610180516103605260006103805260006002905b8060051b6103600151610340526202010f610340516020526000526040600020805460208160051b01600081601f0160051c60058111615497578015614dd457905b808501548160051b6103a00152600101818118614dbc575b50505050506103a051614de657614fd0565b60006103a05160048111615497578015614fcd57905b8060051b6103c0015161044052610440516040526101a051606052614e226104606143da565b61046051614e2f57614fc2565b61044051604052614e41610480614323565b6104805161046052610460515a6101c05060206104c06101c0516101e060008686f190509050614e76573d600060003e3d6000fd5b3d602081183d60201002186104a0526104a06020810151815160200360031b1d90506104805261048051614ea957614fc2565b61044051604052614ebb6104c06143eb565b6104c0516104a05260016104a05118614f3457601d6104c0527f44464d3a4320486f6f6b2063616e6e6f742061646a75737420646562740000006104e0526104c0506104c051806104e001601f826000031636823750506308c379a06104805260206104a052601f19601f6104c051011660440161049cfd5b60026104a05118614f635761048051604052600060605261030051608052600060a052614fa26143fe56614fa2565b610480516040526102e05160605261030051608052600060a052614f856143fe565b610340516080526104605160a0526104805160c052614fa2614bbb565b610320516104805180820182811260008312186154975790509050610320525b600101818118614dfc575b50505b600101818118614d7a575050610320511561500757610320516040526102e05160605261030051608052600160a0526150076143fe565b61032051815250565b6060516323b872dd60c05260405160e0526080516101005260a05161012052602060c0606460dc6000855af161504b573d600060003e3d6000fd5b3d61506257803b156154975760016101405261507a565b60203d106154975760c0518060011c61549757610140525b6101409050511561549757565b620201075460405111156150f25760196060527f44464d3a4320676c6f62616c2064656274206365696c696e670000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b60805160ff81116154975762020006015463bdb09f2e60c05260405160e052602060c0602460dc6000855af161512f573d600060003e3d6000fd5b60203d106154975760c0905051640a3c2abcef818118640a3c2abcef83100218905060a05260605163d4387a9960c05260a05160e052602060c0602460dc6000855af1615181573d600060003e3d6000fd5b60203d106154975760c05050565b6060516323b872dd60c05260805160e0526040516101005260a05161012052602060c0606460dc6000855af16151ca573d600060003e3d6000fd5b3d6151e157803b15615497576001610140526151f9565b60203d106154975760c0518060011c61549757610140525b6101409050511561549757565b6202000560405160205260005260406000205461527a5760146060527f44464d3a4320496e76616c6964206d61726b657400000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b6020615524600039600051638da5cb5b604052602060406004605c845afa6152a9573d600060003e3d6000fd5b60203d10615497576040518060a01c61549757608052608090505133181561532857601060a0527f44464d3a43204f6e6c79206f776e65720000000000000000000000000000000060c05260a05060a0518060c001601f826000031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b565b6020615524600039600051638da5cb5b606052602060606004607c845afa615357573d600060003e3d6000fd5b60203d10615497576060518060a01c6154975760a05260a0905051331461549557602061552460003960005163452a932060c052602060c0600460dc845afa6153a5573d600060003e3d6000fd5b60203d106154975760c0518060a01c61549757610100526101009050513318615438576040511561549557601f610120527f44464d3a4320477561726469616e2063616e206f6e6c792064697361626c65006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd615495565b601b60c0527f44464d3a43204e6f74206f776e6572206f7220677561726469616e000000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b565b600080fd031d19c30da816d03cca1dba412e41c5431d431d026831a002dd431d01b91efa12bf431d12e70e5e003c431d42ab00ee29d939672d4e2c832974431d1a5734e6431d1ebb431d431d431d431d129f431d2e192aa61b02431d07ef0d46001a3053007d016428f500bb00000000000000000000000069420f9e38a4e60a62224c489be4bf7a94402496000000000000000000000000c0deb055a11fd0801040de91a1fac500dc577f00
Loading...
Loading
OVERVIEW
Main controller used to open, adjust, close and liquidate CDP's within Defi.MoneyLoading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.