ETH Price: $2,845.35 (-3.18%)
 

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Deposit380976622025-11-12 21:57:5174 days ago1762984671IN
0x8088773E...6FDF4DCdD
0 ETH0.000004620.0048198
Claim Loot380958592025-11-12 20:57:4574 days ago1762981065IN
0x8088773E...6FDF4DCdD
0 ETH0.000007980.00572916
Deposit380935452025-11-12 19:40:3774 days ago1762976437IN
0x8088773E...6FDF4DCdD
0 ETH0.000005950.00626525
Deposit380935272025-11-12 19:40:0174 days ago1762976401IN
0x8088773E...6FDF4DCdD
0 ETH0.00000440.00528438
Claim Loot380929702025-11-12 19:21:2774 days ago1762975287IN
0x8088773E...6FDF4DCdD
0 ETH0.00000810.00582279
Claim Loot380816612025-11-12 13:04:2974 days ago1762952669IN
0x8088773E...6FDF4DCdD
0 ETH0.000002570.00225394
Claim Loot380802552025-11-12 12:17:3774 days ago1762949857IN
0x8088773E...6FDF4DCdD
0 ETH0.000004310.00378158
Withdraw380782762025-11-12 11:11:3974 days ago1762945899IN
0x8088773E...6FDF4DCdD
0 ETH0.000006720.00797758
Withdraw380775902025-11-12 10:48:4774 days ago1762944527IN
0x8088773E...6FDF4DCdD
0 ETH0.00000410.00455302
Claim Loot380766052025-11-12 10:15:5774 days ago1762942557IN
0x8088773E...6FDF4DCdD
0 ETH0.000005610.00396634
Claim Loot380739702025-11-12 8:48:0774 days ago1762937287IN
0x8088773E...6FDF4DCdD
0 ETH0.000006690.00438617
Claim Loot380646802025-11-12 3:38:2775 days ago1762918707IN
0x8088773E...6FDF4DCdD
0 ETH0.000010330.00745367
Claim Loot380372732025-11-11 12:24:5375 days ago1762863893IN
0x8088773E...6FDF4DCdD
0 ETH0.000009340.00871543
Claim Loot380361262025-11-11 11:46:3975 days ago1762861599IN
0x8088773E...6FDF4DCdD
0 ETH0.000007770.00682303
Claim Loot380080292025-11-10 20:10:0576 days ago1762805405IN
0x8088773E...6FDF4DCdD
0 ETH0.000003110.00163761
Claim Loot380077632025-11-10 20:01:1376 days ago1762804873IN
0x8088773E...6FDF4DCdD
0 ETH0.00000520.00343651
Deposit379991192025-11-10 15:13:0576 days ago1762787585IN
0x8088773E...6FDF4DCdD
0 ETH0.000009040.0108762
Deposit379984152025-11-10 14:49:3776 days ago1762786177IN
0x8088773E...6FDF4DCdD
0 ETH0.000010230.01214972
Claim Loot379981272025-11-10 14:40:0176 days ago1762785601IN
0x8088773E...6FDF4DCdD
0 ETH0.000013650.01197444
Deposit379980872025-11-10 14:38:4176 days ago1762785521IN
0x8088773E...6FDF4DCdD
0 ETH0.000009140.01114965
Deposit379978912025-11-10 14:32:0976 days ago1762785129IN
0x8088773E...6FDF4DCdD
0 ETH0.000008010.00961362
Withdraw379960602025-11-10 13:31:0776 days ago1762781467IN
0x8088773E...6FDF4DCdD
0 ETH0.000005450.00644909
Claim Loot379954662025-11-10 13:11:1976 days ago1762780279IN
0x8088773E...6FDF4DCdD
0 ETH0.000008140.00710898
Withdraw379839672025-11-10 6:48:0176 days ago1762757281IN
0x8088773E...6FDF4DCdD
0 ETH0.000000410.00050941
Claim Loot379783902025-11-10 3:42:0777 days ago1762746127IN
0x8088773E...6FDF4DCdD
0 ETH0.000008360.00645301
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Teller

Compiler Version
vyper:0.4.3

Optimization Enabled:
Yes

Other Settings:
default evmVersion

Contract Source Code (Vyper Json-Input format)

File 1 of 6 : Teller.vy
#                     ___                                    ___          ___     
#            ___     /  /\                                  /  /\        /  /\    
#           /  /\   /  /:/_                                /  /:/_      /  /::\   
#          /  /:/  /  /:/ /\   ___     ___  ___     ___   /  /:/ /\    /  /:/\:\  
#         /  /:/  /  /:/ /:/_ /__/\   /  /\/__/\   /  /\ /  /:/ /:/_  /  /:/~/:/  
#        /  /::\ /__/:/ /:/ /\\  \:\ /  /:/\  \:\ /  /://__/:/ /:/ /\/__/:/ /:/___
#       /__/:/\:\\  \:\/:/ /:/ \  \:\  /:/  \  \:\  /:/ \  \:\/:/ /:/\  \:\/:::::/
#       \__\/  \:\\  \::/ /:/   \  \:\/:/    \  \:\/:/   \  \::/ /:/  \  \::/~~~~ 
#            \  \:\\  \:\/:/     \  \::/      \  \::/     \  \:\/:/    \  \:\     
#             \__\/ \  \::/       \__\/        \__\/       \  \::/      \  \:\    
#                    \__\/                                  \__\/        \__\/    
#
#     ╔═══════════════════════════════════════════════════════════════════════╗
#     ║  ** Teller **                                                         ║
#     ║  Handles deposits, withdrawals, and entry-point for all user actions  ║
#     ╚═══════════════════════════════════════════════════════════════════════╝
#
#     Ripe Protocol License: https://github.com/ripe-foundation/ripe-protocol/blob/master/LICENSE.md
#     Ripe Foundation (C) 2025

# @version 0.4.3
# pragma optimize codesize

implements: Department

exports: addys.__interface__
exports: deptBasics.__interface__

initializes: addys
initializes: deptBasics[addys := addys]

import contracts.modules.Addys as addys
import contracts.modules.DeptBasics as deptBasics
from interfaces import Department
from interfaces import Vault
import interfaces.ConfigStructs as cs

from ethereum.ercs import IERC20
from ethereum.ercs import IERC4626

interface CreditEngine:
    def redeemCollateralFromMany(_redemptions: DynArray[CollateralRedemption, MAX_COLLATERAL_REDEMPTIONS], _greenAmount: uint256, _recipient: address, _caller: address, _shouldTransferBalance: bool, _shouldRefundSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def redeemCollateral(_user: address, _vaultId: uint256, _asset: address, _greenAmount: uint256, _recipient: address, _caller: address, _shouldTransferBalance: bool, _shouldRefundSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def getMaxWithdrawableForAsset(_user: address, _vaultId: uint256, _asset: address, _vaultAddr: address = empty(address), _a: addys.Addys = empty(addys.Addys)) -> uint256: view
    def repayForUser(_user: address, _greenAmount: uint256, _shouldRefundSavingsGreen: bool, _caller: address, _a: addys.Addys = empty(addys.Addys)) -> bool: nonpayable
    def borrowForUser(_user: address, _greenAmount: uint256, _wantsSavingsGreen: bool, _shouldEnterStabPool: bool, _caller: address, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def updateDebtForUser(_user: address, _a: addys.Addys = empty(addys.Addys)) -> bool: nonpayable

interface MissionControl:
    def getTellerWithdrawConfig(_asset: address, _user: address, _caller: address) -> TellerWithdrawConfig: view
    def getTellerDepositConfig(_vaultId: uint256, _asset: address, _user: address) -> TellerDepositConfig: view
    def setUserDelegation(_user: address, _delegate: address, _config: cs.ActionDelegation): nonpayable
    def setUserConfig(_user: address, _config: cs.UserConfig): nonpayable
    def getFirstVaultIdForAsset(_asset: address) -> uint256: view
    def underscoreRegistry() -> address: view
    def shouldCheckLastTouch() -> bool: view

interface AuctionHouse:
    def buyManyFungibleAuctions(_purchases: DynArray[FungAuctionPurchase, MAX_AUCTION_PURCHASES], _greenAmount: uint256, _recipient: address, _caller: address, _shouldTransferBalance: bool, _shouldRefundSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def buyFungibleAuction(_liqUser: address, _vaultId: uint256, _asset: address, _greenAmount: uint256, _recipient: address, _caller: address, _shouldTransferBalance: bool, _shouldRefundSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def liquidateManyUsers(_liqUsers: DynArray[address, MAX_LIQ_USERS], _keeper: address, _wantsSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def liquidateUser(_liqUser: address, _keeper: address, _wantsSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable

interface StabVault:
    def redeemManyFromStabilityPool(_redemptions: DynArray[StabPoolRedemption, MAX_STAB_REDEMPTIONS], _greenAmount: uint256, _recipient: address, _caller: address, _shouldAutoDeposit: bool, _shouldRefundSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def redeemFromStabilityPool(_claimAsset: address, _greenAmount: uint256, _recipient: address, _caller: address, _shouldAutoDeposit: bool, _shouldRefundSavingsGreen: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def claimFromStabilityPool(_claimer: address, _stabAsset: address, _claimAsset: address, _maxUsdValue: uint256, _caller: address, _shouldAutoDeposit: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def claimManyFromStabilityPool(_claimer: address, _claims: DynArray[StabPoolClaim, MAX_STAB_CLAIMS], _caller: address, _shouldAutoDeposit: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable

interface Lootbox:
    def claimLootForManyUsers(_users: DynArray[address, MAX_CLAIM_USERS], _caller: address, _shouldStake: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def updateDepositPoints(_user: address, _vaultId: uint256, _vaultAddr: address, _asset: address, _a: addys.Addys = empty(addys.Addys)): nonpayable
    def claimLootForUser(_user: address, _caller: address, _shouldStake: bool, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable

interface RipeGovVault:
    def depositTokensWithLockDuration(_user: address, _asset: address, _amount: uint256, _lockDuration: uint256, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable
    def adjustLock(_user: address, _asset: address, _newLockDuration: uint256, _a: addys.Addys = empty(addys.Addys)): nonpayable
    def releaseLock(_user: address, _asset: address, _a: addys.Addys = empty(addys.Addys)): nonpayable

interface Ledger:
    def getDepositLedgerData(_user: address, _vaultId: uint256) -> DepositLedgerData: view
    def checkAndUpdateLastTouch(_user: address, _shouldCheck: bool): nonpayable
    def addVaultToUser(_user: address, _vaultId: uint256): nonpayable

interface AddressRegistry:
    def getRegId(_addr: address) -> uint256: view
    def getAddr(_regId: uint256) -> address: view
    def isValidAddr(_addr: address) -> bool: view

interface BondRoom:
    def purchaseRipeBond(_recipient: address, _paymentAsset: address, _paymentAmount: uint256, _lockDuration: uint256, _caller: address, _a: addys.Addys = empty(addys.Addys)) -> uint256: nonpayable

interface PriceDesk:
    def addPriceSnapshot(_asset: address) -> bool: nonpayable

interface CurvePrices:
    def addGreenRefPoolSnapshot() -> bool: nonpayable

interface UnderscoreLedger:
    def isUserWallet(_addr: address) -> bool: view

interface UnderscoreWallet:
    def walletConfig() -> address: view

interface UnderscoreWalletConfig:
    def owner() -> address: view

struct DepositLedgerData:
    isParticipatingInVault: bool
    numUserVaults: uint256

struct TellerDepositConfig:
    canDepositGeneral: bool
    canDepositAsset: bool
    doesVaultSupportAsset: bool
    isUserAllowed: bool
    perUserDepositLimit: uint256
    globalDepositLimit: uint256
    perUserMaxAssetsPerVault: uint256
    perUserMaxVaults: uint256
    canAnyoneDeposit: bool
    minDepositBalance: uint256

struct DepositAction:
    asset: address
    amount: uint256
    vaultAddr: address
    vaultId: uint256

struct TellerWithdrawConfig:
    canWithdrawGeneral: bool
    canWithdrawAsset: bool
    isUserAllowed: bool
    canWithdrawForUser: bool
    minDepositBalance: uint256

struct WithdrawalAction:
    asset: address
    amount: uint256
    vaultAddr: address
    vaultId: uint256

struct CollateralRedemption:
    user: address
    vaultId: uint256
    asset: address
    maxGreenAmount: uint256

struct FungAuctionPurchase:
    liqUser: address
    vaultId: uint256
    asset: address
    maxGreenAmount: uint256

struct StabPoolClaim:
    stabAsset: address
    claimAsset: address
    maxUsdValue: uint256

struct StabPoolRedemption:
    claimAsset: address
    maxGreenAmount: uint256

event TellerDeposit:
    user: indexed(address)
    depositor: indexed(address)
    asset: indexed(address)
    amount: uint256
    vaultAddr: address
    vaultId: uint256

event TellerWithdrawal:
    user: indexed(address)
    asset: indexed(address)
    caller: indexed(address)
    amount: uint256
    vaultAddr: address
    vaultId: uint256
    isDepleted: bool

event UserConfigSet:
    user: indexed(address)
    canAnyoneDeposit: bool
    canAnyoneRepayDebt: bool
    canAnyoneBondForUser: bool
    caller: indexed(address)

event UserDelegationSet:
    user: indexed(address) 
    delegate: indexed(address)
    canWithdraw: bool
    canBorrow: bool
    canClaimFromStabPool: bool 
    canClaimLoot: bool
    caller: indexed(address)

MAX_BALANCE_ACTION: constant(uint256) = 20
MAX_CLAIM_USERS: constant(uint256) = 25
MAX_COLLATERAL_REDEMPTIONS: constant(uint256) = 20
MAX_AUCTION_PURCHASES: constant(uint256) = 20
MAX_LIQ_USERS: constant(uint256) = 50
MAX_STAB_CLAIMS: constant(uint256) = 15
MAX_STAB_REDEMPTIONS: constant(uint256) = 15

STABILITY_POOL_ID: constant(uint256) = 1
RIPE_GOV_VAULT_ID: constant(uint256) = 2
UNDERSCORE_LEDGER_ID: constant(uint256) = 1
UNDERSCORE_LEGOBOOK_ID: constant(uint256) = 3
CURVE_PRICES_ID: constant(uint256) = 2


@deploy
def __init__(_ripeHq: address, _shouldPause: bool):
    addys.__init__(_ripeHq)
    deptBasics.__init__(_shouldPause, False, False) # no minting


############
# Deposits #
############


@nonreentrant
@external
def deposit(
    _asset: address,
    _amount: uint256 = max_value(uint256),
    _user: address = msg.sender,
    _vaultAddr: address = empty(address),
    _vaultId: uint256 = 0,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    return self._deposit(_asset, _amount, _user, _vaultAddr, _vaultId, msg.sender, 0, False, False, True, a)


@nonreentrant
@external
def depositMany(_user: address, _deposits: DynArray[DepositAction, MAX_BALANCE_ACTION]) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    for d: DepositAction in _deposits:
        self._deposit(d.asset, d.amount, _user, d.vaultAddr, d.vaultId, msg.sender, 0, False, False, False, a)
    self._performHousekeeping(False, _user, True, a)
    return len(_deposits)


@external
def depositFromTrusted(
    _user: address,
    _vaultId: uint256,
    _asset: address,
    _amount: uint256,
    _lockDuration: uint256,
    _a: addys.Addys = empty(addys.Addys),
) -> uint256:
    assert addys._isValidRipeAddr(msg.sender) # dev: no perms
    a: addys.Addys = addys._getAddys(_a)
    return self._deposit(_asset, _amount, _user, empty(address), _vaultId, msg.sender, _lockDuration, True, False, False, a)


# core logic


@internal
def _deposit(
    _asset: address,
    _amount: uint256,
    _user: address,
    _vaultAddr: address,
    _vaultId: uint256,
    _depositor: address,
    _lockDuration: uint256,
    _didAlreadyValidateSender: bool,
    _areFundsHereAlready: bool,
    _shouldPerformHouseKeeping: bool,
    _a: addys.Addys,
) -> uint256:
    vaultAddr: address = empty(address)
    vaultId: uint256 = 0
    vaultAddr, vaultId = self._getVaultAddrAndId(_asset, _vaultAddr, _vaultId, _a.vaultBook, _a.missionControl)

    # get ledger data
    d: DepositLedgerData = staticcall Ledger(_a.ledger).getDepositLedgerData(_user, vaultId)
    amount: uint256 = self._validateOnDeposit(_asset, _amount, _user, vaultId, vaultAddr, _depositor, _didAlreadyValidateSender, _areFundsHereAlready, d, _a.missionControl)

    # transfer tokens
    if _areFundsHereAlready:
        assert extcall IERC20(_asset).transfer(vaultAddr, amount, default_return_value=True) # dev: could not transfer
    else:
        assert extcall IERC20(_asset).transferFrom(_depositor, vaultAddr, amount, default_return_value=True) # dev: token transfer failed

    # deposit tokens
    if _lockDuration != 0:
        amount = extcall RipeGovVault(vaultAddr).depositTokensWithLockDuration(_user, _asset, amount, _lockDuration, _a)
    else:
        amount = extcall Vault(vaultAddr).depositTokensInVault(_user, _asset, amount, _a)

    # register vault participation
    if not d.isParticipatingInVault:
        extcall Ledger(_a.ledger).addVaultToUser(_user, vaultId)

    # update lootbox points
    extcall Lootbox(_a.lootbox).updateDepositPoints(_user, vaultId, vaultAddr, _asset, _a)

    # perform house keeping
    if _shouldPerformHouseKeeping:
        self._performHousekeeping(False, _user, True, _a)

    # update price desk (important for share-based assets)
    extcall PriceDesk(_a.priceDesk).addPriceSnapshot(_asset)

    log TellerDeposit(user=_user, depositor=_depositor, asset=_asset, amount=amount, vaultAddr=vaultAddr, vaultId=vaultId)
    return amount


# validation


@view
@internal
def _validateOnDeposit(
    _asset: address,
    _amount: uint256,
    _user: address,
    _vaultId: uint256,
    _vaultAddr: address,
    _depositor: address,
    _didAlreadyValidateSender: bool,
    _areFundsHereAlready: bool,
    _d: DepositLedgerData,
    _missionControl: address,
) -> uint256:
    config: TellerDepositConfig = staticcall MissionControl(_missionControl).getTellerDepositConfig(_vaultId, _asset, _user)
    assert config.canDepositGeneral # dev: protocol deposits disabled
    assert config.canDepositAsset # dev: asset deposits disabled
    assert config.doesVaultSupportAsset # dev: vault does not support asset
    assert config.isUserAllowed # dev: user not on whitelist

    # trusted depositor
    isRipeDepartment: bool = addys._isValidRipeAddr(_depositor)

    # make sure depositor is allowed to deposit for user
    if not _didAlreadyValidateSender and _user != _depositor and not config.canAnyoneDeposit:
        assert isRipeDepartment or self._isUnderscoreWalletOwner(_user, _depositor, _missionControl) # dev: cannot deposit for user

    # avail amount
    holder: address = _depositor
    if _areFundsHereAlready:
        holder = self
    amount: uint256 = min(_amount, staticcall IERC20(_asset).balanceOf(holder))
    assert amount != 0 # dev: cannot deposit 0

    # if depositing from ripe dept, skip these limits
    if isRipeDepartment:
        return amount

    # vault data
    vd: Vault.VaultDataOnDeposit = staticcall Vault(_vaultAddr).getVaultDataOnDeposit(_user, _asset)

    # check max vaults, max assets per vault
    if not _d.isParticipatingInVault:
        assert _d.numUserVaults < config.perUserMaxVaults # dev: reached max vaults

    elif not vd.hasPosition:
        assert vd.numAssets < config.perUserMaxAssetsPerVault # dev: reached max assets per vault

    # per user deposit limit
    availPerUserDeposit: uint256 = self._getAvailPerUserDepositLimit(vd.userBalance, config.perUserDepositLimit)
    assert availPerUserDeposit != 0 # dev: cannot deposit, reached user limit
    amount = min(amount, availPerUserDeposit)

    # global deposit limit
    availGlobalDeposit: uint256 = self._getAvailGlobalDepositLimit(vd.totalBalance, config.globalDepositLimit)
    assert availGlobalDeposit != 0 # dev: cannot deposit, reached global limit
    amount = min(amount, availGlobalDeposit)

    # min balance
    assert amount + vd.userBalance >= config.minDepositBalance # dev: too small a balance

    return amount


# per user deposit limit


@view 
@internal 
def _getAvailPerUserDepositLimit(_userDepositBal: uint256, _perUserDepositLimit: uint256) -> uint256:
    if _perUserDepositLimit == max_value(uint256):
        return max_value(uint256)
    availDeposits: uint256 = 0
    if _perUserDepositLimit > _userDepositBal:
        availDeposits = _perUserDepositLimit - _userDepositBal
    return availDeposits


# global deposit limit


@view 
@internal 
def _getAvailGlobalDepositLimit(_totalDepositBal: uint256, _globalDepositLimit: uint256) -> uint256:
    availDeposits: uint256 = 0
    if _globalDepositLimit > _totalDepositBal:
        availDeposits = _globalDepositLimit - _totalDepositBal
    return availDeposits


###############
# Withdrawals #
###############


@nonreentrant
@external
def withdraw(
    _asset: address,
    _amount: uint256 = max_value(uint256),
    _user: address = msg.sender,
    _vaultAddr: address = empty(address),
    _vaultId: uint256 = 0,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    amount: uint256 = self._withdraw(_asset, _amount, _user, _vaultAddr, _vaultId, msg.sender, a)
    self._performHousekeeping(True, _user, True, a)
    return amount


@nonreentrant
@external
def withdrawMany(_user: address, _withdrawals: DynArray[WithdrawalAction, MAX_BALANCE_ACTION]) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    for w: WithdrawalAction in _withdrawals:
        self._withdraw(w.asset, w.amount, _user, w.vaultAddr, w.vaultId, msg.sender, a)
    self._performHousekeeping(True, _user, True, a)
    return len(_withdrawals)


@internal
def _withdraw(
    _asset: address,
    _amount: uint256,
    _user: address,
    _vaultAddr: address,
    _vaultId: uint256,
    _caller: address,
    _a: addys.Addys,
) -> uint256:
    vaultAddr: address = empty(address)
    vaultId: uint256 = 0
    vaultAddr, vaultId = self._getVaultAddrAndId(_asset, _vaultAddr, _vaultId, _a.vaultBook, _a.missionControl)

    # validation
    config: TellerWithdrawConfig = staticcall MissionControl(_a.missionControl).getTellerWithdrawConfig(_asset, _user, _caller)
    amount: uint256 = self._validateOnWithdrawal(_asset, _amount, _user, vaultAddr, vaultId, _caller, config, _a)

    # withdraw tokens
    isDepleted: bool = False
    amount, isDepleted = extcall Vault(vaultAddr).withdrawTokensFromVault(_user, _asset, amount, _user, _a)

    # check min balance
    if not isDepleted:
        userBalance: uint256 = staticcall Vault(vaultAddr).getTotalAmountForUser(_user, _asset)
        assert userBalance >= config.minDepositBalance # dev: too small a balance

    # update lootbox points
    extcall Lootbox(_a.lootbox).updateDepositPoints(_user, vaultId, vaultAddr, _asset, _a)

    # update price desk (important for share-based assets)
    extcall PriceDesk(_a.priceDesk).addPriceSnapshot(_asset)

    log TellerWithdrawal(user=_user, asset=_asset, caller=_caller, amount=amount, vaultAddr=vaultAddr, vaultId=vaultId, isDepleted=isDepleted)
    return amount


# validation


@view
@internal
def _validateOnWithdrawal(
    _asset: address,
    _amount: uint256,
    _user: address,
    _vaultAddr: address,
    _vaultId: uint256,
    _caller: address,
    _config: TellerWithdrawConfig,
    _a: addys.Addys,
) -> uint256:
    assert _amount != 0 # dev: cannot withdraw 0

    assert _config.canWithdrawGeneral # dev: protocol withdrawals disabled
    assert _config.canWithdrawAsset # dev: asset withdrawals disabled
    assert _config.isUserAllowed # dev: user not on whitelist

    # make sure caller is allowed to withdraw for user
    if _user != _caller and not _config.canWithdrawForUser:
        assert self._isUnderscoreWalletOwner(_user, _caller, _a.missionControl) # dev: not allowed to withdraw for user

    # max withdrawable
    maxWithdrawable: uint256 = staticcall CreditEngine(_a.creditEngine).getMaxWithdrawableForAsset(_user, _vaultId, _asset, _vaultAddr, _a)
    assert maxWithdrawable != 0 # dev: cannot withdraw anything

    return min(_amount, maxWithdrawable)


########
# Debt #
########


# borrow


@nonreentrant
@external
def borrow(
    _greenAmount: uint256 = max_value(uint256),
    _user: address = msg.sender,
    _wantsSavingsGreen: bool = True,
    _shouldEnterStabPool: bool = False,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    self._performHousekeeping(True, _user, False, a)
    return extcall CreditEngine(a.creditEngine).borrowForUser(_user, _greenAmount, _wantsSavingsGreen, _shouldEnterStabPool, msg.sender, a)


# repay


@nonreentrant
@external
def repay(
    _paymentAmount: uint256 = max_value(uint256),
    _user: address = msg.sender,
    _isPaymentSavingsGreen: bool = False,
    _shouldRefundSavingsGreen: bool = True,
) -> bool:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    self._performHousekeeping(False, _user, False, a)
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, a.creditEngine, a.greenToken, a.savingsGreen)
    return extcall CreditEngine(a.creditEngine).repayForUser(_user, greenAmount, _shouldRefundSavingsGreen, msg.sender, a)


# redeem collateral


@nonreentrant
@external
def redeemCollateral(
    _user: address,
    _vaultId: uint256,
    _asset: address,
    _paymentAmount: uint256 = max_value(uint256),
    _isPaymentSavingsGreen: bool = False,
    _shouldTransferBalance: bool = False,
    _shouldRefundSavingsGreen: bool = True,
    _recipient: address = msg.sender,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, a.creditEngine, a.greenToken, a.savingsGreen)
    redemptions: DynArray[CollateralRedemption, MAX_COLLATERAL_REDEMPTIONS] = [CollateralRedemption(user=_user, vaultId=_vaultId, asset=_asset, maxGreenAmount=greenAmount)]
    greenSpent: uint256 = extcall CreditEngine(a.creditEngine).redeemCollateralFromMany(redemptions, max_value(uint256), _recipient, msg.sender, _shouldTransferBalance, _shouldRefundSavingsGreen, a)
    self._performHousekeeping(False, _recipient, True, a)
    return greenSpent


@nonreentrant
@external
def redeemCollateralFromMany(
    _redemptions: DynArray[CollateralRedemption, MAX_COLLATERAL_REDEMPTIONS],
    _paymentAmount: uint256 = max_value(uint256),
    _isPaymentSavingsGreen: bool = False,
    _shouldTransferBalance: bool = False,
    _shouldRefundSavingsGreen: bool = True,
    _recipient: address = msg.sender,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, a.creditEngine, a.greenToken, a.savingsGreen)
    greenSpent: uint256 = extcall CreditEngine(a.creditEngine).redeemCollateralFromMany(_redemptions, greenAmount, _recipient, msg.sender, _shouldTransferBalance, _shouldRefundSavingsGreen, a)
    self._performHousekeeping(False, _recipient, True, a)
    return greenSpent


################
# Liquidations #
################


# liquidate users


@nonreentrant
@external
def liquidateUser(
    _liqUser: address,
    _wantsSavingsGreen: bool = True,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    keeperRewards: uint256 = extcall AuctionHouse(a.auctionHouse).liquidateUser(_liqUser, msg.sender, _wantsSavingsGreen, a)
    self._performHousekeeping(False, msg.sender, True, a)
    return keeperRewards


@nonreentrant
@external
def liquidateManyUsers(
    _liqUsers: DynArray[address, MAX_LIQ_USERS],
    _wantsSavingsGreen: bool = True,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    keeperRewards: uint256 = extcall AuctionHouse(a.auctionHouse).liquidateManyUsers(_liqUsers, msg.sender, _wantsSavingsGreen, a)
    self._performHousekeeping(False, msg.sender, True, a)
    return keeperRewards


# buy fungible auctions


@nonreentrant
@external
def buyFungibleAuction(
    _liqUser: address,
    _vaultId: uint256,
    _asset: address,
    _paymentAmount: uint256 = max_value(uint256),
    _isPaymentSavingsGreen: bool = False,
    _shouldTransferBalance: bool = False,
    _shouldRefundSavingsGreen: bool = True,
    _recipient: address = msg.sender,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, a.auctionHouse, a.greenToken, a.savingsGreen)
    greenSpent: uint256 = extcall AuctionHouse(a.auctionHouse).buyFungibleAuction(_liqUser, _vaultId, _asset, greenAmount, _recipient, msg.sender, _shouldTransferBalance, _shouldRefundSavingsGreen, a)
    self._performHousekeeping(False, _recipient, True, a)
    return greenSpent


@nonreentrant
@external
def buyManyFungibleAuctions(
    _purchases: DynArray[FungAuctionPurchase, MAX_AUCTION_PURCHASES],
    _paymentAmount: uint256 = max_value(uint256),
    _isPaymentSavingsGreen: bool = False,
    _shouldTransferBalance: bool = False,
    _shouldRefundSavingsGreen: bool = True,
    _recipient: address = msg.sender,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, a.auctionHouse, a.greenToken, a.savingsGreen)
    greenSpent: uint256 = extcall AuctionHouse(a.auctionHouse).buyManyFungibleAuctions(_purchases, greenAmount, _recipient, msg.sender, _shouldTransferBalance, _shouldRefundSavingsGreen, a)
    self._performHousekeeping(False, _recipient, True, a)
    return greenSpent


###################
# Stability Pools #
###################


# deposit green into stab pool


@nonreentrant
@external
def convertToSavingsGreenAndDepositIntoStabPool(_user: address = msg.sender, _greenAmount: uint256 = max_value(uint256)) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()

    # transfer GREEN to this contract
    greenAmount: uint256 = min(_greenAmount, staticcall IERC20(a.greenToken).balanceOf(msg.sender))
    assert greenAmount != 0 # dev: cannot deposit 0 green
    assert extcall IERC20(a.greenToken).transferFrom(msg.sender, self, greenAmount, default_return_value=True) # dev: token transfer failed

    # put GREEN into sGREEN
    assert extcall IERC20(a.greenToken).approve(a.savingsGreen, greenAmount, default_return_value=True) # dev: green approval failed
    sGreenAmount: uint256 = extcall IERC4626(a.savingsGreen).deposit(greenAmount, self)
    assert extcall IERC20(a.greenToken).approve(a.savingsGreen, 0, default_return_value=True) # dev: green approval failed

    return self._deposit(a.savingsGreen, sGreenAmount, _user, empty(address), STABILITY_POOL_ID, msg.sender, 0, False, True, True, a)


# claims


@nonreentrant
@external
def claimFromStabilityPool(
    _vaultId: uint256,
    _stabAsset: address,
    _claimAsset: address,
    _maxUsdValue: uint256 = max_value(uint256),
    _user: address = msg.sender,
    _shouldAutoDeposit: bool = False,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    vaultAddr: address = staticcall AddressRegistry(a.vaultBook).getAddr(_vaultId)
    claimUsdValue: uint256 = extcall StabVault(vaultAddr).claimFromStabilityPool(_user, _stabAsset, _claimAsset, _maxUsdValue, msg.sender, _shouldAutoDeposit, a)
    self._performHousekeeping(True, _user, True, a)
    return claimUsdValue


@nonreentrant
@external
def claimManyFromStabilityPool(
    _vaultId: uint256,
    _claims: DynArray[StabPoolClaim, MAX_STAB_CLAIMS],
    _user: address = msg.sender,
    _shouldAutoDeposit: bool = False,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    vaultAddr: address = staticcall AddressRegistry(a.vaultBook).getAddr(_vaultId)
    claimUsdValue: uint256 = extcall StabVault(vaultAddr).claimManyFromStabilityPool(_user, _claims, msg.sender, _shouldAutoDeposit, a)
    self._performHousekeeping(True, _user, True, a)
    return claimUsdValue


# redemptions


@nonreentrant
@external
def redeemFromStabilityPool(
    _vaultId: uint256,
    _claimAsset: address,
    _paymentAmount: uint256 = max_value(uint256),
    _recipient: address = msg.sender,
    _shouldAutoDeposit: bool = False,
    _isPaymentSavingsGreen: bool = False,
    _shouldRefundSavingsGreen: bool = True,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    vaultAddr: address = staticcall AddressRegistry(a.vaultBook).getAddr(_vaultId)
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, vaultAddr, a.greenToken, a.savingsGreen)
    greenSpent: uint256 = extcall StabVault(vaultAddr).redeemFromStabilityPool(_claimAsset, greenAmount, _recipient, msg.sender, _shouldAutoDeposit, _shouldRefundSavingsGreen, a)
    self._performHousekeeping(False, _recipient, True, a)
    return greenSpent


@nonreentrant
@external
def redeemManyFromStabilityPool(
    _vaultId: uint256,
    _redemptions: DynArray[StabPoolRedemption, MAX_STAB_REDEMPTIONS],
    _paymentAmount: uint256 = max_value(uint256),
    _recipient: address = msg.sender,
    _shouldAutoDeposit: bool = False,
    _isPaymentSavingsGreen: bool = False,
    _shouldRefundSavingsGreen: bool = True,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    vaultAddr: address = staticcall AddressRegistry(a.vaultBook).getAddr(_vaultId)
    greenAmount: uint256 = self._handleGreenPayment(_isPaymentSavingsGreen, _paymentAmount, vaultAddr, a.greenToken, a.savingsGreen)
    greenSpent: uint256 = extcall StabVault(vaultAddr).redeemManyFromStabilityPool(_redemptions, greenAmount, _recipient, msg.sender, _shouldAutoDeposit, _shouldRefundSavingsGreen, a)
    self._performHousekeeping(False, _recipient, True, a)
    return greenSpent


###########
# Rewards #
###########


# claim loot


@nonreentrant
@external
def claimLoot(_user: address = msg.sender, _shouldStake: bool = True) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    totalRipe: uint256 = extcall Lootbox(a.lootbox).claimLootForUser(_user, msg.sender, _shouldStake, a)
    self._performHousekeeping(False, _user, True, a)
    return totalRipe


# claim for many users


@nonreentrant
@external
def claimLootForManyUsers(_users: DynArray[address, MAX_CLAIM_USERS], _shouldStake: bool = True) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    totalRipe: uint256 = extcall Lootbox(a.lootbox).claimLootForManyUsers(_users, msg.sender, _shouldStake, a)
    self._performHousekeeping(False, msg.sender, True, a)
    return totalRipe


##################
# Ripe Gov Vault #
##################


@external
def depositIntoGovVault(
    _asset: address,
    _amount: uint256,
    _lockDuration: uint256,
    _user: address = msg.sender,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    if _user != msg.sender:
        assert self._isUnderscoreAddr(msg.sender, a.missionControl) or self._isUnderscoreWalletOwner(_user, msg.sender, a.missionControl) # dev: cannot deposit
    return self._deposit(_asset, _amount, _user, empty(address), RIPE_GOV_VAULT_ID, msg.sender, _lockDuration, True, False, True, a)


@nonreentrant
@external
def adjustLock(_asset: address, _newLockDuration: uint256, _user: address = msg.sender):
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    vaultAddr: address = staticcall AddressRegistry(a.vaultBook).getAddr(RIPE_GOV_VAULT_ID)

    # validate underscore wallet
    if _user != msg.sender:
        assert self._isUnderscoreAddr(msg.sender, a.missionControl) or self._isUnderscoreWalletOwner(_user, msg.sender, a.missionControl) # dev: no perms

    extcall RipeGovVault(vaultAddr).adjustLock(_user, _asset, _newLockDuration, a)
    self._performHousekeeping(False, _user, True, a)


@nonreentrant
@external
def releaseLock(_asset: address, _user: address = msg.sender):
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    vaultAddr: address = staticcall AddressRegistry(a.vaultBook).getAddr(RIPE_GOV_VAULT_ID)

    # validate underscore wallet
    if _user != msg.sender:
        assert self._isUnderscoreAddr(msg.sender, a.missionControl) or self._isUnderscoreWalletOwner(_user, msg.sender, a.missionControl) # dev: no perms

    extcall RipeGovVault(vaultAddr).releaseLock(_user, _asset, a)
    self._performHousekeeping(False, _user, True, a)


##################
# Bond Purchases #
##################


@nonreentrant
@external
def purchaseRipeBond(
    _paymentAsset: address,
    _paymentAmount: uint256 = max_value(uint256),
    _lockDuration: uint256 = 0,
    _recipient: address = msg.sender,
) -> uint256:
    assert not deptBasics.isPaused # dev: contract paused
    a: addys.Addys = addys._getAddys()
    paymentAmount: uint256 = min(_paymentAmount, staticcall IERC20(_paymentAsset).balanceOf(msg.sender))
    assert extcall IERC20(_paymentAsset).transferFrom(msg.sender, a.bondRoom, paymentAmount, default_return_value=True) # dev: token transfer failed
    ripePayout: uint256 = extcall BondRoom(a.bondRoom).purchaseRipeBond(_recipient, _paymentAsset, paymentAmount, _lockDuration, msg.sender, a)
    self._performHousekeeping(False, _recipient, True, a)
    return ripePayout


###############
# User Config #
###############


@external
def setUserConfig(
    _user: address = msg.sender,
    _canAnyoneDeposit: bool = True,
    _canAnyoneRepayDebt: bool = True,
    _canAnyoneBondForUser: bool = True,
) -> bool:
    assert not deptBasics.isPaused # dev: contract paused
    mc: address = addys._getMissionControlAddr()

    # validate underscore wallet
    if _user != msg.sender:
        assert self._isUnderscoreWalletOwner(_user, msg.sender, mc) # dev: not owner of underscore wallet

    return self._setUserConfig(_user, _canAnyoneDeposit, _canAnyoneRepayDebt, _canAnyoneBondForUser, mc)


@internal
def _setUserConfig(
    _user: address,
    _canAnyoneDeposit: bool,
    _canAnyoneRepayDebt: bool,
    _canAnyoneBondForUser: bool,
    _mc: address
) -> bool:
    userConfig: cs.UserConfig = cs.UserConfig(
        canAnyoneDeposit=_canAnyoneDeposit,
        canAnyoneRepayDebt=_canAnyoneRepayDebt,
        canAnyoneBondForUser=_canAnyoneBondForUser,
    )
    extcall MissionControl(_mc).setUserConfig(_user, userConfig)
    log UserConfigSet(user=_user, canAnyoneDeposit=_canAnyoneDeposit, canAnyoneRepayDebt=_canAnyoneRepayDebt, canAnyoneBondForUser=_canAnyoneBondForUser, caller=msg.sender)
    return True


# delegation


@external
def setUserDelegation(
    _delegate: address,
    _user: address = msg.sender,
    _canWithdraw: bool = True,
    _canBorrow: bool = True,
    _canClaimFromStabPool: bool = True,
    _canClaimLoot: bool = True,
) -> bool:
    assert not deptBasics.isPaused # dev: contract paused
    assert _delegate != empty(address) # dev: invalid delegate
    assert _delegate != _user # dev: cannot delegate to self

    # validate underscore wallet
    mc: address = addys._getMissionControlAddr()
    if _user != msg.sender:
        assert self._isUnderscoreWalletOwner(_user, msg.sender, mc) # dev: not owner of underscore wallet
        assert _delegate != msg.sender # dev: cannot delegate to owner

    return self._setUserDelegation(_delegate, _user, _canWithdraw, _canBorrow, _canClaimFromStabPool, _canClaimLoot, mc)


@internal
def _setUserDelegation(
    _delegate: address,
    _user: address,
    _canWithdraw: bool,
    _canBorrow: bool,
    _canClaimFromStabPool: bool,
    _canClaimLoot: bool,
    _mc: address
) -> bool:
    config: cs.ActionDelegation = cs.ActionDelegation(
        canWithdraw=_canWithdraw,
        canBorrow=_canBorrow,
        canClaimFromStabPool=_canClaimFromStabPool,
        canClaimLoot=_canClaimLoot,
    )
    extcall MissionControl(_mc).setUserDelegation(_user, _delegate, config)
    log UserDelegationSet(user=_user, delegate=_delegate, canWithdraw=_canWithdraw, canBorrow=_canBorrow, canClaimFromStabPool=_canClaimFromStabPool, canClaimLoot=_canClaimLoot, caller=msg.sender)
    return True


# underscore helpers


@external
def setUndyLegoAccess(_legoAddr: address) -> bool:
    # NOTE: failing gracefully here to not brick underscore wallets

    mc: address = addys._getMissionControlAddr()
    if mc == empty(address):
        return False

    if _legoAddr == empty(address):
        return False

    if not self._isUnderscoreWallet(msg.sender, mc):
        return False

    # set config
    self._setUserConfig(msg.sender, True, True, True, mc)
    self._setUserDelegation(_legoAddr, msg.sender, True, True, True, True, mc)
    return True


#############
# Utilities #
#############


# housekeeping


@internal
def _performHousekeeping(
    _isHigherRisk: bool,
    _user: address,
    _shouldUpdateDebt: bool,
    _a: addys.Addys,
):
    # one action per block
    shouldCheckLastTouch: bool = False
    if staticcall MissionControl(_a.missionControl).shouldCheckLastTouch():
        shouldCheckLastTouch = _isHigherRisk and not self._isUnderscoreWallet(_user, _a.missionControl)
    extcall Ledger(_a.ledger).checkAndUpdateLastTouch(_user, shouldCheckLastTouch)

    # update green ref pool snapshot
    curvePrices: address = staticcall AddressRegistry(_a.priceDesk).getAddr(CURVE_PRICES_ID)
    if curvePrices != empty(address):
        extcall CurvePrices(curvePrices).addGreenRefPoolSnapshot()

    # update debt
    if _shouldUpdateDebt:
        if _isHigherRisk:
            assert extcall CreditEngine(_a.creditEngine).updateDebtForUser(_user, _a) # dev: bad debt health
        else:
            extcall CreditEngine(_a.creditEngine).updateDebtForUser(_user, _a)


# vault info 


@view
@internal
def _getVaultAddrAndId(
    _asset: address,
    _vaultAddr: address,
    _vaultId: uint256,
    _vaultBook: address,
    _missionControl: address,
) -> (address, uint256):
    vaultAddr: address = empty(address)
    vaultId: uint256 = 0

    # if no vault data specified, get first vault id for asset
    if _vaultAddr == empty(address) and _vaultId == 0:
        vaultId = staticcall MissionControl(_missionControl).getFirstVaultIdForAsset(_asset)
        assert vaultId != 0 # dev: invalid asset
        vaultAddr = staticcall AddressRegistry(_vaultBook).getAddr(vaultId)
        assert vaultAddr != empty(address) # dev: invalid vault id

    # vault id
    elif _vaultId != 0:
        vaultAddr = staticcall AddressRegistry(_vaultBook).getAddr(_vaultId)
        assert vaultAddr != empty(address) # dev: invalid vault id
        vaultId = _vaultId
        if _vaultAddr != empty(address):
            assert vaultAddr == _vaultAddr # dev: vault id and vault addr mismatch

    # vault addr
    elif _vaultAddr != empty(address):
        vaultId = staticcall AddressRegistry(_vaultBook).getRegId(_vaultAddr) # dev: invalid vault addr
        assert vaultId != 0 # dev: invalid vault addr
        vaultAddr = _vaultAddr

    return vaultAddr, vaultId


# green payments


@internal
def _handleGreenPayment(
    _isPaymentSavingsGreen: bool,
    _amount: uint256,
    _recipient: address,
    _greenToken: address,
    _savingsGreen: address,
) -> uint256:
    asset: address = _greenToken
    if _isPaymentSavingsGreen:
        asset = _savingsGreen

    amount: uint256 = min(_amount, staticcall IERC20(asset).balanceOf(msg.sender))
    assert amount != 0 # dev: cannot transfer 0 amount
    assert _recipient != empty(address) # dev: invalid recipient

    # savings green - unwrap it and transfer to recipient
    if _isPaymentSavingsGreen:
        assert extcall IERC20(_savingsGreen).transferFrom(msg.sender, self, amount, default_return_value=True) # dev: token transfer failed
        amount = extcall IERC4626(_savingsGreen).redeem(amount, _recipient, self) # dev: savings green redeem failed

    # normal green - transfer directly to recipient
    else:
        assert extcall IERC20(_greenToken).transferFrom(msg.sender, _recipient, amount, default_return_value=True) # dev: token transfer failed

    return amount


# underscore ownership check


@view
@external
def isUnderscoreWalletOwner(_user: address, _caller: address, _mc: address = empty(address)) -> bool:
    missionControl: address = _mc
    if _mc == empty(address):
        missionControl = addys._getMissionControlAddr()
    return self._isUnderscoreWalletOwner(_user, _caller, missionControl)


@view
@internal
def _isUnderscoreWallet(_user: address, _mc: address) -> bool:
    underscore: address = staticcall MissionControl(_mc).underscoreRegistry()
    if underscore == empty(address):
        return False

    undyLedger: address = staticcall AddressRegistry(underscore).getAddr(UNDERSCORE_LEDGER_ID)
    if undyLedger == empty(address):
        return False

    # check if user is underscore wallet
    return staticcall UnderscoreLedger(undyLedger).isUserWallet(_user)


@view
@internal
def _isUnderscoreWalletOwner(_user: address, _caller: address, _mc: address) -> bool:
    if not self._isUnderscoreWallet(_user, _mc):
        return False

    walletConfig: address = staticcall UnderscoreWallet(_user).walletConfig()
    if walletConfig == empty(address):
        return False

    # check if caller is owner
    return staticcall UnderscoreWalletConfig(walletConfig).owner() == _caller


# underscore address check


@view
@internal
def _isUnderscoreAddr(_addr: address, _mc: address) -> bool:
    underscore: address = staticcall MissionControl(_mc).underscoreRegistry()
    if underscore == empty(address):
        return False

    # check if addr is in underscore registry (Loot Distributor)
    if staticcall AddressRegistry(underscore).isValidAddr(_addr):
        return True

    undyLegoBook: address = staticcall AddressRegistry(underscore).getAddr(UNDERSCORE_LEGOBOOK_ID)
    if undyLegoBook == empty(address):
        return False

    return staticcall AddressRegistry(undyLegoBook).isValidAddr(_addr)


########  ######## ########   #######   ######  #### ######## 
##     ## ##       ##     ## ##     ## ##    ##  ##     ##    
##     ## ##       ##     ## ##     ## ##        ##     ##    
##     ## ######   ########  ##     ##  ######   ##     ##    
##     ## ##       ##        ##     ##       ##  ##     ##    
##     ## ##       ##        ##     ## ##    ##  ##     ##    
########  ######## ##         #######   ######  ####    ##

File 2 of 6 : Addys.vy
# Ripe Protocol License: https://github.com/ripe-foundation/ripe-protocol/blob/master/LICENSE.md
# Ripe Foundation (C) 2025

# @version 0.4.3

interface RipeHq:
    def isValidAddr(_addr: address) -> bool: view
    def getAddr(_regId: uint256) -> address: view

interface Switchboard:
    def isSwitchboardAddr(_addr: address) -> bool: view

interface VaultBook:
    def isVaultBookAddr(_addr: address) -> bool: view

struct Addys:
    hq: address
    greenToken: address
    savingsGreen: address
    ripeToken: address
    ledger: address
    missionControl: address
    switchboard: address
    priceDesk: address
    vaultBook: address
    auctionHouse: address
    auctionHouseNft: address
    boardroom: address
    bondRoom: address
    creditEngine: address
    endaoment: address
    humanResources: address
    lootbox: address
    teller: address

# hq
RIPE_HQ_FOR_ADDYS: immutable(address)

# core addys
GREEN_TOKEN_ID: constant(uint256) = 1
SAVINGS_GREEN_ID: constant(uint256) = 2
RIPE_TOKEN_ID: constant(uint256) = 3
LEDGER_ID: constant(uint256) = 4
MISSION_CONTROL_ID: constant(uint256) = 5
SWITCHBOARD_ID: constant(uint256) = 6
PRICE_DESK_ID: constant(uint256) = 7
VAULT_BOOK_ID: constant(uint256) = 8
AUCTION_HOUSE_ID: constant(uint256) = 9
AUCTION_HOUSE_NFT_ID: constant(uint256) = 10
BOARDROOM_ID: constant(uint256) = 11
BOND_ROOM_ID: constant(uint256) = 12
CREDIT_ENGINE_ID: constant(uint256) = 13
ENDAOMENT_ID: constant(uint256) = 14
HUMAN_RESOURCES_ID: constant(uint256) = 15
LOOTBOX_ID: constant(uint256) = 16
TELLER_ID: constant(uint256) = 17


@deploy
def __init__(_ripeHq: address):
    assert _ripeHq != empty(address) # dev: invalid ripe hq
    RIPE_HQ_FOR_ADDYS = _ripeHq


########
# Core #
########


@view
@external
def getAddys() -> Addys:
    return self._generateAddys()


@view
@internal
def _getAddys(_addys: Addys = empty(Addys)) -> Addys:
    if _addys.hq != empty(address):
        return _addys
    return self._generateAddys()


@view
@internal
def _generateAddys() -> Addys:
    hq: address = RIPE_HQ_FOR_ADDYS
    return Addys(
        hq=hq,
        greenToken=staticcall RipeHq(hq).getAddr(GREEN_TOKEN_ID),
        savingsGreen=staticcall RipeHq(hq).getAddr(SAVINGS_GREEN_ID),
        ripeToken=staticcall RipeHq(hq).getAddr(RIPE_TOKEN_ID),
        ledger=staticcall RipeHq(hq).getAddr(LEDGER_ID),
        missionControl=staticcall RipeHq(hq).getAddr(MISSION_CONTROL_ID),
        switchboard=staticcall RipeHq(hq).getAddr(SWITCHBOARD_ID),
        priceDesk=staticcall RipeHq(hq).getAddr(PRICE_DESK_ID),
        vaultBook=staticcall RipeHq(hq).getAddr(VAULT_BOOK_ID),
        auctionHouse=staticcall RipeHq(hq).getAddr(AUCTION_HOUSE_ID),
        auctionHouseNft=staticcall RipeHq(hq).getAddr(AUCTION_HOUSE_NFT_ID),
        boardroom=staticcall RipeHq(hq).getAddr(BOARDROOM_ID),
        bondRoom=staticcall RipeHq(hq).getAddr(BOND_ROOM_ID),
        creditEngine=staticcall RipeHq(hq).getAddr(CREDIT_ENGINE_ID),
        endaoment=staticcall RipeHq(hq).getAddr(ENDAOMENT_ID),
        humanResources=staticcall RipeHq(hq).getAddr(HUMAN_RESOURCES_ID),
        lootbox=staticcall RipeHq(hq).getAddr(LOOTBOX_ID),
        teller=staticcall RipeHq(hq).getAddr(TELLER_ID),
    )


##########
# Tokens #
##########


@view
@internal
def _getGreenToken() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(GREEN_TOKEN_ID)


@view
@internal
def _getSavingsGreen() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(SAVINGS_GREEN_ID)


@view
@internal
def _getRipeToken() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(RIPE_TOKEN_ID)


###########
# Helpers #
###########


# ripe hq


@view
@external
def getRipeHq() -> address:
    return self._getRipeHq()


@view
@internal
def _getRipeHq() -> address:
    return RIPE_HQ_FOR_ADDYS


# utils


@view
@internal
def _isValidRipeAddr(_addr: address) -> bool:
    hq: address = RIPE_HQ_FOR_ADDYS
    
    # core departments
    if staticcall RipeHq(hq).isValidAddr(_addr):
        return True

    # vault book
    vaultBook: address = staticcall RipeHq(hq).getAddr(VAULT_BOOK_ID)
    if vaultBook != empty(address) and staticcall VaultBook(vaultBook).isVaultBookAddr(_addr):
        return True

    # switchboard config
    switchboard: address = staticcall RipeHq(hq).getAddr(SWITCHBOARD_ID)
    if switchboard != empty(address) and staticcall Switchboard(switchboard).isSwitchboardAddr(_addr):
        return True

    return False


@view
@internal
def _isSwitchboardAddr(_addr: address) -> bool:
    switchboard: address = staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(SWITCHBOARD_ID)
    if switchboard == empty(address):
        return False
    return staticcall Switchboard(switchboard).isSwitchboardAddr(_addr)


###############
# Departments #
###############


# ledger


@view
@internal
def _getLedgerId() -> uint256:
    return LEDGER_ID


@view
@internal
def _getLedgerAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(LEDGER_ID)


# mission control


@view
@internal
def _getMissionControlId() -> uint256:
    return MISSION_CONTROL_ID


@view
@internal
def _getMissionControlAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(MISSION_CONTROL_ID)


# switchboard


@view
@internal
def _getSwitchboardId() -> uint256:
    return SWITCHBOARD_ID


@view
@internal
def _getSwitchboardAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(SWITCHBOARD_ID)


# price desk


@view
@internal
def _getPriceDeskId() -> uint256:
    return PRICE_DESK_ID


@view
@internal
def _getPriceDeskAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(PRICE_DESK_ID)


# vault book


@view
@internal
def _getVaultBookId() -> uint256:
    return VAULT_BOOK_ID


@view
@internal
def _getVaultBookAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(VAULT_BOOK_ID)


# auction house


@view
@internal
def _getAuctionHouseId() -> uint256:
    return AUCTION_HOUSE_ID


@view
@internal
def _getAuctionHouseAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(AUCTION_HOUSE_ID)


# auction house nft


@view
@internal
def _getAuctionHouseNftId() -> uint256:
    return AUCTION_HOUSE_NFT_ID


@view
@internal
def _getAuctionHouseNftAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(AUCTION_HOUSE_NFT_ID)


# boardroom


@view
@internal
def _getBoardroomId() -> uint256:
    return BOARDROOM_ID


@view
@internal
def _getBoardroomAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(BOARDROOM_ID)


# bond room


@view
@internal
def _getBondRoomId() -> uint256:
    return BOND_ROOM_ID


@view
@internal
def _getBondRoomAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(BOND_ROOM_ID)


# credit engine


@view
@internal
def _getCreditEngineId() -> uint256:
    return CREDIT_ENGINE_ID


@view
@internal
def _getCreditEngineAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(CREDIT_ENGINE_ID)


# endaoment


@view
@internal
def _getEndaomentId() -> uint256:
    return ENDAOMENT_ID


@view
@internal
def _getEndaomentAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(ENDAOMENT_ID)


# human resources


@view
@internal
def _getHumanResourcesId() -> uint256:
    return HUMAN_RESOURCES_ID


@view
@internal
def _getHumanResourcesAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(HUMAN_RESOURCES_ID)


# lootbox


@view
@internal
def _getLootboxId() -> uint256:
    return LOOTBOX_ID


@view
@internal
def _getLootboxAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(LOOTBOX_ID)


# teller


@view
@internal
def _getTellerId() -> uint256:
    return TELLER_ID


@view
@internal
def _getTellerAddr() -> address:
    return staticcall RipeHq(RIPE_HQ_FOR_ADDYS).getAddr(TELLER_ID)

File 3 of 6 : Vyper_contract.vy
# @version 0.4.3


###########
# Minting #
###########


@view
@external
def canMintGreen() -> bool:
    # used in RipeHq.vy
    ...


@view
@external
def canMintRipe() -> bool:
    # used in RipeHq.vy
    ...


########
# Ripe #
########


@view
@external
def isPaused() -> bool:
    ...


@external
def pause(_shouldPause: bool):
    ...


@external
def recoverFunds(_recipient: address, _asset: address):
    ...

@external
def recoverFundsMany(_recipient: address, _assets: DynArray[address, 20]):
    ...

File 4 of 6 : DeptBasics.vy
# Ripe Protocol License: https://github.com/ripe-foundation/ripe-protocol/blob/master/LICENSE.md
# Ripe Foundation (C) 2025

# @version 0.4.3

uses: addys
implements: dept

import contracts.modules.Addys as addys
import interfaces.Department as dept
from ethereum.ercs import IERC20

event DepartmentPauseModified:
    isPaused: bool

event DepartmentFundsRecovered:
    asset: indexed(address)
    recipient: indexed(address)
    balance: uint256

# config
isPaused: public(bool)

CAN_MINT_GREEN: immutable(bool)
CAN_MINT_RIPE: immutable(bool)

MAX_RECOVER_ASSETS: constant(uint256) = 20


@deploy
def __init__(_shouldPause: bool, _canMintGreen: bool, _canMintRipe: bool):
    self.isPaused = _shouldPause

    CAN_MINT_GREEN = _canMintGreen
    CAN_MINT_RIPE = _canMintRipe


###########
# Minting #
###########


@view
@external
def canMintGreen() -> bool:
    return CAN_MINT_GREEN


@view
@external
def canMintRipe() -> bool:
    return CAN_MINT_RIPE


########
# Ripe #
########


# activate


@external
def pause(_shouldPause: bool):
    assert addys._isSwitchboardAddr(msg.sender) # dev: no perms
    assert _shouldPause != self.isPaused # dev: no change
    self.isPaused = _shouldPause
    log DepartmentPauseModified(isPaused=_shouldPause)


# recover funds


@external
def recoverFunds(_recipient: address, _asset: address):
    assert addys._isSwitchboardAddr(msg.sender) # dev: no perms
    self._recoverFunds(_recipient, _asset)


@external
def recoverFundsMany(_recipient: address, _assets: DynArray[address, MAX_RECOVER_ASSETS]):
    assert addys._isSwitchboardAddr(msg.sender) # dev: no perms
    for a: address in _assets:
        self._recoverFunds(_recipient, a)


@internal
def _recoverFunds(_recipient: address, _asset: address):
    assert empty(address) not in [_recipient, _asset] # dev: invalid recipient or asset
    balance: uint256 = staticcall IERC20(_asset).balanceOf(self)
    assert balance != 0 # dev: nothing to recover

    assert extcall IERC20(_asset).transfer(_recipient, balance, default_return_value=True) # dev: recovery failed
    log DepartmentFundsRecovered(asset=_asset, recipient=_recipient, balance=balance)

File 5 of 6 : Vyper_contract.vy
# @version 0.4.3

import contracts.modules.Addys as addys

struct VaultDataOnDeposit:
    hasPosition: bool
    numAssets: uint256
    userBalance: uint256
    totalBalance: uint256


########
# Core #
########


@external
def depositTokensInVault(
    _user: address,
    _asset: address,
    _amount: uint256,
    _a: addys.Addys = empty(addys.Addys),
) -> uint256:
    ...


@external
def withdrawTokensFromVault(
    _user: address,
    _asset: address,
    _amount: uint256,
    _recipient: address,
    _a: addys.Addys = empty(addys.Addys),
) -> (uint256, bool):
    ...


@external
def transferBalanceWithinVault(
    _asset: address,
    _fromUser: address,
    _toUser: address,
    _transferAmount: uint256,
    _a: addys.Addys = empty(addys.Addys),
) -> (uint256, bool):
    ...


####################
# Needs For Others #
####################


@view
@external
def numUserAssets(_user: address) -> uint256:
    # used in AuctionHouse.vy
    ...


@view
@external
def userAssets(_user: address, _index: uint256) -> address:
    # used in Lootbox.vy
    ...


@view
@external
def getVaultDataOnDeposit(_user: address, _asset: address) -> VaultDataOnDeposit:
    # used in Teller.vy
    ...


@view
@external
def getUserLootBoxShare(_user: address, _asset: address) -> uint256:
    # used in Lootbox.vy
    ...


@view
@external
def getUserAssetAndAmountAtIndex(_user: address, _index: uint256) -> (address, uint256):
    # used in CreditEngine.vy
    ...


@view
@external
def getUserAssetAtIndexAndHasBalance(_user: address, _index: uint256) -> (address, bool):
    # used in Lootbox.vy and AuctionHouse.vy
    ...


###############
# Other Utils #
###############


@view
@external
def getTotalAmountForUser(_user: address, _asset: address) -> uint256:
    ...


@view
@external
def getTotalAmountForVault(_asset: address) -> uint256:
    ...


########
# Data #
########


@view
@external
def isUserInVaultAsset(_user: address, _asset: address) -> bool:
    ...


@view
@external
def doesUserHaveBalance(_user: address, _asset: address) -> bool:
    ...


@view
@external
def isSupportedVaultAsset(_asset: address) -> bool:
    ...


# remove data


@external
def deregisterUserAsset(_user: address, _asset: address) -> bool:
    ...


@external
def deregisterVaultAsset(_asset: address) -> bool:
    ...


# utils


@view
@external
def getNumUserAssets(_user: address) -> uint256:
    ...


@view
@external
def getNumVaultAssets() -> uint256:
    ...


@view
@external
def doesVaultHaveAnyFunds() -> bool:
    ...


########
# Ripe #
########


@view
@external
def isPaused() -> bool:
    ...


@external
def pause(_shouldPause: bool):
    ...


@external
def recoverFunds(_recipient: address, _asset: address):
    ...

@external
def recoverFundsMany(_recipient: address, _assets: DynArray[address, 20]):
    ...

File 6 of 6 : Vyper_contract.vy
# @version 0.4.3

MAX_VAULTS_PER_ASSET: constant(uint256) = 10

struct GenConfig:
    perUserMaxVaults: uint256
    perUserMaxAssetsPerVault: uint256
    priceStaleTime: uint256
    canDeposit: bool
    canWithdraw: bool
    canBorrow: bool
    canRepay: bool
    canClaimLoot: bool
    canLiquidate: bool
    canRedeemCollateral: bool
    canRedeemInStabPool: bool
    canBuyInAuction: bool
    canClaimInStabPool: bool

struct GenDebtConfig:
    perUserDebtLimit: uint256
    globalDebtLimit: uint256
    minDebtAmount: uint256
    numAllowedBorrowers: uint256
    maxBorrowPerInterval: uint256
    numBlocksPerInterval: uint256
    minDynamicRateBoost: uint256
    maxDynamicRateBoost: uint256
    increasePerDangerBlock: uint256
    maxBorrowRate: uint256
    maxLtvDeviation: uint256
    keeperFeeRatio: uint256
    minKeeperFee: uint256
    maxKeeperFee: uint256
    isDaowryEnabled: bool
    ltvPaybackBuffer: uint256
    genAuctionParams: AuctionParams

struct HrConfig:
    contribTemplate: address
    maxCompensation: uint256
    minCliffLength: uint256
    maxStartDelay: uint256
    minVestingLength: uint256
    maxVestingLength: uint256

struct RipeBondConfig:
    asset: address
    amountPerEpoch: uint256
    canBond: bool
    minRipePerUnit: uint256
    maxRipePerUnit: uint256
    maxRipePerUnitLockBonus: uint256
    epochLength: uint256
    shouldAutoRestart: bool
    restartDelayBlocks: uint256

struct RipeRewardsConfig:
    arePointsEnabled: bool
    ripePerBlock: uint256
    borrowersAlloc: uint256
    stakersAlloc: uint256
    votersAlloc: uint256
    genDepositorsAlloc: uint256
    autoStakeRatio: uint256
    autoStakeDurationRatio: uint256
    stabPoolRipePerDollarClaimed: uint256

struct RipeGovVaultConfig:
    lockTerms: LockTerms
    assetWeight: uint256
    shouldFreezeWhenBadDebt: bool

struct LockTerms:
    minLockDuration: uint256
    maxLockDuration: uint256
    maxLockBoost: uint256
    canExit: bool
    exitFee: uint256

struct AuctionParams:
    hasParams: bool
    startDiscount: uint256
    maxDiscount: uint256
    delay: uint256
    duration: uint256

struct AssetConfig:
    vaultIds: DynArray[uint256, MAX_VAULTS_PER_ASSET]
    stakersPointsAlloc: uint256
    voterPointsAlloc: uint256
    perUserDepositLimit: uint256
    globalDepositLimit: uint256
    minDepositBalance: uint256
    debtTerms: DebtTerms
    shouldBurnAsPayment: bool
    shouldTransferToEndaoment: bool
    shouldSwapInStabPools: bool
    shouldAuctionInstantly: bool
    canDeposit: bool
    canWithdraw: bool
    canRedeemCollateral: bool
    canRedeemInStabPool: bool
    canBuyInAuction: bool
    canClaimInStabPool: bool
    specialStabPoolId: uint256
    customAuctionParams: AuctionParams
    whitelist: address
    isNft: bool

struct DebtTerms:
    ltv: uint256
    redemptionThreshold: uint256
    liqThreshold: uint256
    liqFee: uint256
    borrowRate: uint256
    daowry: uint256

struct UserConfig:
    canAnyoneDeposit: bool
    canAnyoneRepayDebt: bool
    canAnyoneBondForUser: bool

struct ActionDelegation:
    canWithdraw: bool
    canBorrow: bool
    canClaimFromStabPool: bool
    canClaimLoot: bool

struct VaultLite:
    vaultId: uint256
    asset: address

Settings
{
  "outputSelection": {
    "contracts/core/Teller.vy": [
      "evm.bytecode",
      "evm.deployedBytecode",
      "abi"
    ]
  },
  "search_paths": [
    "."
  ]
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"depositor","type":"address"},{"indexed":true,"name":"asset","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"vaultAddr","type":"address"},{"indexed":false,"name":"vaultId","type":"uint256"}],"name":"TellerDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"asset","type":"address"},{"indexed":true,"name":"caller","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"vaultAddr","type":"address"},{"indexed":false,"name":"vaultId","type":"uint256"},{"indexed":false,"name":"isDepleted","type":"bool"}],"name":"TellerWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"canAnyoneDeposit","type":"bool"},{"indexed":false,"name":"canAnyoneRepayDebt","type":"bool"},{"indexed":false,"name":"canAnyoneBondForUser","type":"bool"},{"indexed":true,"name":"caller","type":"address"}],"name":"UserConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":true,"name":"delegate","type":"address"},{"indexed":false,"name":"canWithdraw","type":"bool"},{"indexed":false,"name":"canBorrow","type":"bool"},{"indexed":false,"name":"canClaimFromStabPool","type":"bool"},{"indexed":false,"name":"canClaimLoot","type":"bool"},{"indexed":true,"name":"caller","type":"address"}],"name":"UserDelegationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"isPaused","type":"bool"}],"name":"DepartmentPauseModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"asset","type":"address"},{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"balance","type":"uint256"}],"name":"DepartmentFundsRecovered","type":"event"},{"inputs":[],"name":"getAddys","outputs":[{"components":[{"name":"hq","type":"address"},{"name":"greenToken","type":"address"},{"name":"savingsGreen","type":"address"},{"name":"ripeToken","type":"address"},{"name":"ledger","type":"address"},{"name":"missionControl","type":"address"},{"name":"switchboard","type":"address"},{"name":"priceDesk","type":"address"},{"name":"vaultBook","type":"address"},{"name":"auctionHouse","type":"address"},{"name":"auctionHouseNft","type":"address"},{"name":"boardroom","type":"address"},{"name":"bondRoom","type":"address"},{"name":"creditEngine","type":"address"},{"name":"endaoment","type":"address"},{"name":"humanResources","type":"address"},{"name":"lootbox","type":"address"},{"name":"teller","type":"address"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRipeHq","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canMintGreen","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canMintRipe","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_shouldPause","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_recipient","type":"address"},{"name":"_asset","type":"address"}],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_recipient","type":"address"},{"name":"_assets","type":"address[]"}],"name":"recoverFundsMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_asset","type":"address"}],"name":"deposit","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"}],"name":"deposit","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_user","type":"address"}],"name":"deposit","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_vaultAddr","type":"address"}],"name":"deposit","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_vaultAddr","type":"address"},{"name":"_vaultId","type":"uint256"}],"name":"deposit","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"vaultAddr","type":"address"},{"name":"vaultId","type":"uint256"}],"name":"_deposits","type":"tuple[]"}],"name":"depositMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_lockDuration","type":"uint256"}],"name":"depositFromTrusted","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_lockDuration","type":"uint256"},{"components":[{"name":"hq","type":"address"},{"name":"greenToken","type":"address"},{"name":"savingsGreen","type":"address"},{"name":"ripeToken","type":"address"},{"name":"ledger","type":"address"},{"name":"missionControl","type":"address"},{"name":"switchboard","type":"address"},{"name":"priceDesk","type":"address"},{"name":"vaultBook","type":"address"},{"name":"auctionHouse","type":"address"},{"name":"auctionHouseNft","type":"address"},{"name":"boardroom","type":"address"},{"name":"bondRoom","type":"address"},{"name":"creditEngine","type":"address"},{"name":"endaoment","type":"address"},{"name":"humanResources","type":"address"},{"name":"lootbox","type":"address"},{"name":"teller","type":"address"}],"name":"_a","type":"tuple"}],"name":"depositFromTrusted","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"}],"name":"withdraw","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_user","type":"address"}],"name":"withdraw","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_vaultAddr","type":"address"}],"name":"withdraw","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_vaultAddr","type":"address"},{"name":"_vaultId","type":"uint256"}],"name":"withdraw","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"vaultAddr","type":"address"},{"name":"vaultId","type":"uint256"}],"name":"_withdrawals","type":"tuple[]"}],"name":"withdrawMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"borrow","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_greenAmount","type":"uint256"}],"name":"borrow","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_greenAmount","type":"uint256"},{"name":"_user","type":"address"}],"name":"borrow","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_greenAmount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_wantsSavingsGreen","type":"bool"}],"name":"borrow","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_greenAmount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_wantsSavingsGreen","type":"bool"},{"name":"_shouldEnterStabPool","type":"bool"}],"name":"borrow","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"repay","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAmount","type":"uint256"}],"name":"repay","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAmount","type":"uint256"},{"name":"_user","type":"address"}],"name":"repay","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAmount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"repay","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAmount","type":"uint256"},{"name":"_user","type":"address"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"repay","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"}],"name":"redeemCollateral","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"}],"name":"redeemCollateral","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"redeemCollateral","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"}],"name":"redeemCollateral","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"redeemCollateral","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"},{"name":"_recipient","type":"address"}],"name":"redeemCollateral","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"user","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"}],"name":"redeemCollateralFromMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"user","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"}],"name":"redeemCollateralFromMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"user","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"redeemCollateralFromMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"user","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"}],"name":"redeemCollateralFromMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"user","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"redeemCollateralFromMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"user","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"},{"name":"_recipient","type":"address"}],"name":"redeemCollateralFromMany","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"}],"name":"liquidateUser","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_wantsSavingsGreen","type":"bool"}],"name":"liquidateUser","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUsers","type":"address[]"}],"name":"liquidateManyUsers","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUsers","type":"address[]"},{"name":"_wantsSavingsGreen","type":"bool"}],"name":"liquidateManyUsers","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"}],"name":"buyFungibleAuction","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"}],"name":"buyFungibleAuction","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"buyFungibleAuction","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"}],"name":"buyFungibleAuction","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"buyFungibleAuction","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_liqUser","type":"address"},{"name":"_vaultId","type":"uint256"},{"name":"_asset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"},{"name":"_recipient","type":"address"}],"name":"buyFungibleAuction","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"liqUser","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_purchases","type":"tuple[]"}],"name":"buyManyFungibleAuctions","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"liqUser","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_purchases","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"}],"name":"buyManyFungibleAuctions","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"liqUser","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_purchases","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"buyManyFungibleAuctions","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"liqUser","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_purchases","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"}],"name":"buyManyFungibleAuctions","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"liqUser","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_purchases","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"buyManyFungibleAuctions","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"liqUser","type":"address"},{"name":"vaultId","type":"uint256"},{"name":"asset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_purchases","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldTransferBalance","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"},{"name":"_recipient","type":"address"}],"name":"buyManyFungibleAuctions","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"convertToSavingsGreenAndDepositIntoStabPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"}],"name":"convertToSavingsGreenAndDepositIntoStabPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_greenAmount","type":"uint256"}],"name":"convertToSavingsGreenAndDepositIntoStabPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_stabAsset","type":"address"},{"name":"_claimAsset","type":"address"}],"name":"claimFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_stabAsset","type":"address"},{"name":"_claimAsset","type":"address"},{"name":"_maxUsdValue","type":"uint256"}],"name":"claimFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_stabAsset","type":"address"},{"name":"_claimAsset","type":"address"},{"name":"_maxUsdValue","type":"uint256"},{"name":"_user","type":"address"}],"name":"claimFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_stabAsset","type":"address"},{"name":"_claimAsset","type":"address"},{"name":"_maxUsdValue","type":"uint256"},{"name":"_user","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"}],"name":"claimFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"stabAsset","type":"address"},{"name":"claimAsset","type":"address"},{"name":"maxUsdValue","type":"uint256"}],"name":"_claims","type":"tuple[]"}],"name":"claimManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"stabAsset","type":"address"},{"name":"claimAsset","type":"address"},{"name":"maxUsdValue","type":"uint256"}],"name":"_claims","type":"tuple[]"},{"name":"_user","type":"address"}],"name":"claimManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"stabAsset","type":"address"},{"name":"claimAsset","type":"address"},{"name":"maxUsdValue","type":"uint256"}],"name":"_claims","type":"tuple[]"},{"name":"_user","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"}],"name":"claimManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_claimAsset","type":"address"}],"name":"redeemFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_claimAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"}],"name":"redeemFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_claimAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"}],"name":"redeemFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_claimAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"}],"name":"redeemFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_claimAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"redeemFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"name":"_claimAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"redeemFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"claimAsset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"}],"name":"redeemManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"claimAsset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"}],"name":"redeemManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"claimAsset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"}],"name":"redeemManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"claimAsset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"}],"name":"redeemManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"claimAsset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"},{"name":"_isPaymentSavingsGreen","type":"bool"}],"name":"redeemManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_vaultId","type":"uint256"},{"components":[{"name":"claimAsset","type":"address"},{"name":"maxGreenAmount","type":"uint256"}],"name":"_redemptions","type":"tuple[]"},{"name":"_paymentAmount","type":"uint256"},{"name":"_recipient","type":"address"},{"name":"_shouldAutoDeposit","type":"bool"},{"name":"_isPaymentSavingsGreen","type":"bool"},{"name":"_shouldRefundSavingsGreen","type":"bool"}],"name":"redeemManyFromStabilityPool","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimLoot","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"}],"name":"claimLoot","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_shouldStake","type":"bool"}],"name":"claimLoot","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_users","type":"address[]"}],"name":"claimLootForManyUsers","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_users","type":"address[]"},{"name":"_shouldStake","type":"bool"}],"name":"claimLootForManyUsers","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_lockDuration","type":"uint256"}],"name":"depositIntoGovVault","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_lockDuration","type":"uint256"},{"name":"_user","type":"address"}],"name":"depositIntoGovVault","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_newLockDuration","type":"uint256"}],"name":"adjustLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_newLockDuration","type":"uint256"},{"name":"_user","type":"address"}],"name":"adjustLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"}],"name":"releaseLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_user","type":"address"}],"name":"releaseLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAsset","type":"address"}],"name":"purchaseRipeBond","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"}],"name":"purchaseRipeBond","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_lockDuration","type":"uint256"}],"name":"purchaseRipeBond","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_paymentAsset","type":"address"},{"name":"_paymentAmount","type":"uint256"},{"name":"_lockDuration","type":"uint256"},{"name":"_recipient","type":"address"}],"name":"purchaseRipeBond","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setUserConfig","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"}],"name":"setUserConfig","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_canAnyoneDeposit","type":"bool"}],"name":"setUserConfig","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_canAnyoneDeposit","type":"bool"},{"name":"_canAnyoneRepayDebt","type":"bool"}],"name":"setUserConfig","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_canAnyoneDeposit","type":"bool"},{"name":"_canAnyoneRepayDebt","type":"bool"},{"name":"_canAnyoneBondForUser","type":"bool"}],"name":"setUserConfig","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"}],"name":"setUserDelegation","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"},{"name":"_user","type":"address"}],"name":"setUserDelegation","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"},{"name":"_user","type":"address"},{"name":"_canWithdraw","type":"bool"}],"name":"setUserDelegation","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"},{"name":"_user","type":"address"},{"name":"_canWithdraw","type":"bool"},{"name":"_canBorrow","type":"bool"}],"name":"setUserDelegation","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"},{"name":"_user","type":"address"},{"name":"_canWithdraw","type":"bool"},{"name":"_canBorrow","type":"bool"},{"name":"_canClaimFromStabPool","type":"bool"}],"name":"setUserDelegation","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"},{"name":"_user","type":"address"},{"name":"_canWithdraw","type":"bool"},{"name":"_canBorrow","type":"bool"},{"name":"_canClaimFromStabPool","type":"bool"},{"name":"_canClaimLoot","type":"bool"}],"name":"setUserDelegation","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_legoAddr","type":"address"}],"name":"setUndyLegoAccess","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_caller","type":"address"}],"name":"isUnderscoreWalletOwner","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_user","type":"address"},{"name":"_caller","type":"address"},{"name":"_mc","type":"address"}],"name":"isUnderscoreWalletOwner","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_ripeHq","type":"address"},{"name":"_shouldPause","type":"bool"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"}]

615bad51503461008b576020615c555f395f518060a01c61008b5760a0526020615c755f395f518060011c61008b5760c05260a05160405261003f610065565b60c051604052604036606037610053610076565b615b6d61008f61000039615bcd610000f35b6040511561008b57604051615b6d52565b6040515f55606051615b8d52608051615bad52565b5f80fd5f3560e01c6005600560118306026157a001601b395f5160088160ff16838360181c0260181c0660031b8260081c61ffff1601601839505f51818160201c14600336111615613572578061fffe1636103482600116021761579c578060101c61ffff16565b6102406100726106c0613576565b6106c0f35b60206100836040613bcf565b6040f35b6020615b8d60403960206040f35b6020615bad60403960206040f35b6004358060011c61579c5760e052336040526100c0610100613bd9565b610100511561579c575f5460e0511461579c5760e0515f557fdd3e5b8936c85b0f24d27616bb5cd2bc155c70d2d372e734a6e1a5be777acd9b60e051610100526020610100a1005b6004358060a01c61579c57610120526024358060a01c61579c576101405233604052610135610160613bd9565b610160511561579c57604061012060405e61014e613c9b565b005b6004358060a01c61579c5761012052602435600401601481351161579c5780355f816014811161579c5780156101a857905b8060051b6020850101358060a01c61579c578160051b6101600152600101818118610182575b505080610140525050336040526101c06103e0613bd9565b6103e0511561579c575f610140516014811161579c57801561020c57905b8060051b61016001516103e052610120516040526103e051606052610201613c9b565b6001018181186101de575b5050005b5f5460405260206040f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e605233610e8052604036610ea0376102e7565b602435610e605233610e8052604036610ea0376102e7565b602435610e60526044358060a01c61579c57610e8052604036610ea0376102e7565b602435610e60526044358060a01c61579c57610e80526064358060a01c61579c57610ea0525f610ec0526102e7565b602435610e60526044358060a01c61579c57610e80526064358060a01c61579c57610ea052608435610ec0525b6004358060a01c61579c57610e40525f5c60011461579c5760015f5d5f5461579c57610240366106c03761031c611120613d9e565b61112061024081610ee05e50602060a0610e406107405e336107e05260603661080037600161086052610240610ee06108805e61035a611120614a14565b6111205f5f5df35b6004358060a01c61579c57610e4052602435600401601481351161579c5780355f816014811161579c5780156103e457905b8060071b60208501018160071b610e800181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118610394575b505080610e605250505f5c60011461579c5760015f5d5f5461579c57610240366106c037610413611ac0613d9e565b611ac0610240816118805e505f610e60516014811161579c57801561049557905b8060071b610e8001608081611ac05e506040611ac06107405e610e405161078052611b00516107a052611b20516107c052336107e052608036610800376102406118806108805e610486611b40614a14565b611b4050600101818118610434575b50505f61012052610e4051610140526001610160526102406118806101805e6104bc614798565b610e6051611ac0526020611ac05f5f5df35b61024036610e80376105f9565b60a4358060a01c61579c57610e805260c4358060a01c61579c57610ea05260e4358060a01c61579c57610ec052610104358060a01c61579c57610ee052610124358060a01c61579c57610f0052610144358060a01c61579c57610f2052610164358060a01c61579c57610f4052610184358060a01c61579c57610f60526101a4358060a01c61579c57610f80526101c4358060a01c61579c57610fa0526101e4358060a01c61579c57610fc052610204358060a01c61579c57610fe052610224358060a01c61579c5761100052610244358060a01c61579c5761102052610264358060a01c61579c5761104052610284358060a01c61579c57611060526102a4358060a01c61579c57611080526102c4358060a01c61579c576110a0525b6004358060a01c61579c57610e40526044358060a01c61579c57610e6052336040526106266110c0613f91565b6110c0511561579c57610240610e806106c05e610644611300613d9e565b611300610240816110c05e506020610e60516107405260643561076052610e4051610780525f6107a0526024356107c052336107e05260843561080052600161082052604036610840376102406110c06108805e6106a3611300614a14565b611300f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61104052336110605260403661108037610774565b60243561104052336110605260403661108037610774565b602435611040526044358060a01c61579c576110605260403661108037610774565b602435611040526044358060a01c61579c57611060526064358060a01c61579c57611080525f6110a052610774565b602435611040526044358060a01c61579c57611060526064358060a01c61579c57611080526084356110a0525b6004358060a01c61579c57611020525f5c60011461579c5760015f5d5f5461579c57610240366106c0376107a9611300613d9e565b611300610240816110c05e5060a06110206108a05e33610940526102406110c06109605e6107d8611320614f8b565b611320516113005260016101205261106051610140526001610160526102406110c06101805e610806614798565b60206113005f5f5df35b6004358060a01c61579c5761102052602435600401601481351161579c5780355f816014811161579c57801561089257905b8060071b60208501018160071b6110600181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118610842575b5050806110405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376108c1611ca0613d9e565b611ca061024081611a605e505f611040516014811161579c57801561093c57905b8060071b61106001608081611ca05e506040611ca06108a05e611020516108e052611ce05161090052611d0051610920523361094052610240611a606109605e61092d611d20614f8b565b611d20506001018181186108e2575b50506001610120526110205161014052600161016052610240611a606101805e610964614798565b61104051611ca0526020611ca05f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b405233610b60526001610b80525f610ba052610a56565b600435610b405233610b60526001610b80525f610ba052610a56565b600435610b40526024358060a01c61579c57610b60526001610b80525f610ba052610a56565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80525f610ba052610a56565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80526064358060011c61579c57610ba0525b5f5c60011461579c5760015f5d5f5461579c57610240366106c037610a7c610e00613d9e565b610e0061024081610bc05e50600161012052610b6051610140525f61016052610240610bc06101805e610aad614798565b6020610d60516357b13c7f610e0052610b6051610e2052610b4051610e40526040610b80610e605e33610ea052610240610bc0610ec05e6020610e006102e4610e1c5f855af1610aff573d5f5f3e3d5ffd5b60203d1061579c57610e0090505f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b405233610b60525f610b80526001610ba052610bf2565b600435610b405233610b60525f610b80526001610ba052610bf2565b600435610b40526024358060a01c61579c57610b60525f610b80526001610ba052610bf2565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80526001610ba052610bf2565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80526064358060011c61579c57610ba0525b5f5c60011461579c5760015f5d5f5461579c57610240366106c037610c18610e00613d9e565b610e0061024081610bc05e505f61012052610b6051610140525f61016052610240610bc06101805e610c48614798565b610b8051604052610b4051606052610d6051608052610be05160a052610c005160c052610c76610e206152db565b610e2051610e00526020610d605163d2302444610e2052610b6051610e4052610e0051610e6052610ba051610e805233610ea052610240610bc0610ec05e6020610e206102c4610e3c5f855af1610ccf573d5f5f3e3d5ffd5b3d602081183d602010021880610e2001610e401161579c57610e20518060011c61579c57611100525061110090505f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b8052604036610ba0376001610be05233610c0052610e3e565b606435610b8052604036610ba0376001610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba0525f610bc0526001610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc0526001610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05260e4358060a01c61579c57610c00525b6004358060a01c61579c57610b40526044358060a01c61579c57610b60525f5c60011461579c5760015f5d5f5461579c57610240366106c037610e82610e60613d9e565b610e6061024081610c205e50610ba051604052610b8051606052610dc051608052610c405160a052610c605160c052610ebc610e806152db565b610e8051610e6052610b4051610ea052602435610ec052610b6051610ee052610e6051610f00526001610e8052610dc051632ca47d996118c052610300806118e052806118e0015f610e80518083528060071b5f826014811161579c578015610f4457905b8060071b610ea0018160071b6020880101608082825e5050600101818118610f21575b505082016020019150509050810190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61190052610c00516119205233611940526040610bc06119605e610240610c206119a05e5060206118c0610d246118dc5f855af1610fb5573d5f5f3e3d5ffd5b60203d1061579c576118c09050516118a0525f61012052610c005161014052600161016052610240610c206101805e610fec614798565b60206118a05f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611560526040366115803760016115c052336115e052611132565b602435611560526040366115803760016115c052336115e052611132565b602435611560526044358060011c61579c57611580525f6115a05260016115c052336115e052611132565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a05260016115c052336115e052611132565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c052336115e052611132565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c05260a4358060a01c61579c576115e0525b600435600401601481351161579c5780355f816014811161579c5780156111a557905b8060071b60208501018160071b610b600181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118611155575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376111d4611840613d9e565b611840610240816116005e5061158051604052611560516060526117a0516080526116205160a0526116405160c05261120e6118606152db565b61186051611840526117a051632ca47d9961188052610300806118a052806118a0015f610b40518083528060071b5f826014811161579c57801561127157905b8060071b610b60018160071b6020880101608082825e505060010181811861124e575b50508201602001915050905081019050611840516118c0526115e0516118e052336119005260406115a06119205e6102406116006119605e506020611880610d2461189c5f855af16112c5573d5f5f3e3d5ffd5b60203d1061579c57611880905051611860525f610120526115e051610140526001610160526102406116006101805e6112fc614798565b60206118605f5f5df35b6001610b6052611321565b6024358060011c61579c57610b60525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037611356610dc0613d9e565b610dc061024081610b805e50610ca05163c36746b4610de052610b4051610e005233610e2052610b6051610e4052610240610b80610e605e6020610de06102a4610dfc5f855af16113a9573d5f5f3e3d5ffd5b60203d1061579c57610de0905051610dc0525f610120523361014052600161016052610240610b806101805e6113dd614798565b6020610dc05f5f5df35b60016111a052611402565b6024358060011c61579c576111a0525b600435600401603281351161579c5780355f816032811161579c57801561144b57905b8060051b6020850101358060a01c61579c578160051b610b600152600101818118611425575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c03761147a611400613d9e565b611400610240816111c05e506112e0516336caaa9d611420526102a0806114405280611440015f610b40518083528060051b5f826032811161579c5780156114dc57905b8060051b610b6001518160051b6020880101526001018181186114be575b5050820160200191505090508101905033611460526111a051611480526102406111c06114a05e50602061142061090461143c5f855af161151f573d5f5f3e3d5ffd5b60203d1061579c57611420905051611400525f6101205233610140526001610160526102406111c06101805e611553614798565b60206114005f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b8052604036610ba0376001610be05233610c0052611699565b606435610b8052604036610ba0376001610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba0525f610bc0526001610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc0526001610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05260e4358060a01c61579c57610c00525b6004358060a01c61579c57610b40526044358060a01c61579c57610b60525f5c60011461579c5760015f5d5f5461579c57610240366106c0376116dd610e60613d9e565b610e6061024081610c205e50610ba051604052610b8051606052610d4051608052610c405160a052610c605160c052611717610e806152db565b610e8051610e6052610d4051636dce8d20610ea052610b4051610ec052602435610ee052610b6051610f0052610e6051610f2052610c0051610f405233610f60526040610bc0610f805e610240610c20610fc05e6020610ea0610344610ebc5f855af1611786573d5f5f3e3d5ffd5b60203d1061579c57610ea0905051610e80525f61012052610c005161014052600161016052610240610c206101805e6117bd614798565b6020610e805f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611560526040366115803760016115c052336115e052611903565b602435611560526040366115803760016115c052336115e052611903565b602435611560526044358060011c61579c57611580525f6115a05260016115c052336115e052611903565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a05260016115c052336115e052611903565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c052336115e052611903565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c05260a4358060a01c61579c576115e0525b600435600401601481351161579c5780355f816014811161579c57801561197657905b8060071b60208501018160071b610b600181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118611926575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376119a5611840613d9e565b611840610240816116005e506115805160405261156051606052611720516080526116205160a0526116405160c0526119df6118606152db565b61186051611840526117205163896c6d1461188052610300806118a052806118a0015f610b40518083528060071b5f826014811161579c578015611a4257905b8060071b610b60018160071b6020880101608082825e5050600101818118611a1f575b50508201602001915050905081019050611840516118c0526115e0516118e052336119005260406115a06119205e6102406116006119605e506020611880610d2461189c5f855af1611a96573d5f5f3e3d5ffd5b60203d1061579c57611880905051611860525f610120526115e051610140526001610160526102406116006101805e611acd614798565b60206118605f5f5df35b33610e40527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e6052611b56565b6004358060a01c61579c57610e40527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e6052611b56565b6004358060a01c61579c57610e4052602435610e60525b5f5c60011461579c5760015f5d5f5461579c57610240366106c037611b7c6110c0613d9e565b6110c061024081610e805e50610e6051610ea0516370a082316110e052336111005260206110e060246110fc845afa611bb7573d5f5f3e3d5ffd5b60203d1061579c576110e0905051808281188284100218905090506110c0526110c0511561579c57610ea0516323b872dd6110e052336111005230611120526110c0516111405260206110e060646110fc5f855af1611c18573d5f5f3e3d5ffd5b3d611c2f57803b1561579c57600161116052611c59565b3d602081183d6020100218806110e0016111001161579c576110e0518060011c61579c5761116052505b6111609050511561579c57610ea05163095ea7b36110e052610ec051611100526110c0516111205260206110e060446110fc5f855af1611c9b573d5f5f3e3d5ffd5b3d611cb257803b1561579c57600161114052611cdc565b3d602081183d6020100218806110e0016111001161579c576110e0518060011c61579c5761114052505b6111409050511561579c57610ec051636e553f65611100526110c0516111205230611140526020611100604461111c5f855af1611d1b573d5f5f3e3d5ffd5b60203d1061579c576111009050516110e052610ea05163095ea7b361110052610ec051611120525f611140526020611100604461111c5f855af1611d61573d5f5f3e3d5ffd5b3d611d7857803b1561579c57600161116052611da2565b3d602081183d602010021880611100016111201161579c57611100518060011c61579c5761116052505b6111609050511561579c576020610ec051610740526110e05161076052610e4051610780525f6107a05260016107c052336107e05260403661080037600161084052600161086052610240610e806108805e611dff611100614a14565b6111005f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b805233610ba0525f610bc052611e97565b606435610b805233610ba0525f610bc052611e97565b606435610b80526084358060a01c61579c57610ba0525f610bc052611e97565b606435610b80526084358060a01c61579c57610ba05260a4358060011c61579c57610bc0525b6024358060a01c61579c57610b40526044358060a01c61579c57610b60525f5c60011461579c5760015f5d5f5461579c57610240366106c037611edb610e20613d9e565b610e2061024081610be05e50610ce05163d81f84b7610e4052600435610e60526020610e406024610e5c845afa611f14573d5f5f3e3d5ffd5b3d602081183d602010021880610e4001610e601161579c57610e40518060a01c61579c57610e805250610e80905051610e2052610e20516348b62d4e610e6052610ba051610e8052610b4051610ea0526040610b60610ec05e33610f0052610bc051610f2052610240610be0610f405e6020610e60610304610e7c5f855af1611f9f573d5f5f3e3d5ffd5b60203d1061579c57610e60905051610e4052600161012052610ba05161014052600161016052610240610be06101805e611fd7614798565b6020610e405f5f5df35b33611100525f61112052612028565b6044358060a01c61579c57611100525f61112052612028565b6044358060a01c61579c57611100526064358060011c61579c57611120525b602435600401600f81351161579c5780355f81600f811161579c57801561209157905b60608102602085010160608202610b600181358060a01c61579c57815260208201358060a01c61579c57602082015260408201356040820152505060010181811861204b575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376120c0611380613d9e565b611380610240816111405e506112405163d81f84b76113a0526004356113c05260206113a060246113bc845afa6120f9573d5f5f3e3d5ffd5b3d602081183d6020100218806113a0016113c01161579c576113a0518060a01c61579c576113e052506113e0905051611380526113805163fb0163a26113c0526102c0611100516113e0528061140052806113e0015f610b4051808352606081025f82600f811161579c57801561218f57905b60608102610b6001606082026020880101606082825e505060010181811861216c575b50508201602001915050905081019050336114205261112051611440526102406111406114605e5060206113c06108846113dc5f855af16121d2573d5f5f3e3d5ffd5b60203d1061579c576113c09050516113a05260016101205261110051610140526001610160526102406111406101805e61220a614798565b60206113a05f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b605233610b8052604036610ba0376001610be05261234e565b604435610b605233610b8052604036610ba0376001610be05261234e565b604435610b60526064358060a01c61579c57610b8052604036610ba0376001610be05261234e565b604435610b60526064358060a01c61579c57610b80526084358060011c61579c57610ba0525f610bc0526001610be05261234e565b604435610b60526064358060a01c61579c57610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc0526001610be05261234e565b604435610b60526064358060a01c61579c57610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be0525b6024358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612383610e40613d9e565b610e4061024081610c005e50610d005163d81f84b7610e6052600435610e80526020610e606024610e7c845afa6123bc573d5f5f3e3d5ffd5b3d602081183d602010021880610e6001610e801161579c57610e60518060a01c61579c57610ea05250610ea0905051610e4052610bc051604052610b6051606052610e4051608052610c205160a052610c405160c05261241d610e806152db565b610e8051610e6052610e405163ce566e1d610ea052610b4051610ec052610e6051610ee052610b8051610f005233610f2052610ba051610f4052610be051610f6052610240610c00610f805e6020610ea0610304610ebc5f855af1612484573d5f5f3e3d5ffd5b60203d1061579c57610ea0905051610e80525f61012052610b805161014052600161016052610240610c006101805e6124bb614798565b6020610e805f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610f205233610f4052604036610f60376001610fa0526125ff565b604435610f205233610f4052604036610f60376001610fa0526125ff565b604435610f20526064358060a01c61579c57610f4052604036610f60376001610fa0526125ff565b604435610f20526064358060a01c61579c57610f40526084358060011c61579c57610f60525f610f80526001610fa0526125ff565b604435610f20526064358060a01c61579c57610f40526084358060011c61579c57610f605260a4358060011c61579c57610f80526001610fa0526125ff565b604435610f20526064358060a01c61579c57610f40526084358060011c61579c57610f605260a4358060011c61579c57610f805260c4358060011c61579c57610fa0525b602435600401600f81351161579c5780355f81600f811161579c57801561265657905b8060061b60208501018160061b610b600181358060a01c61579c578152602082013560208201525050600101818118612622575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c037612685611200613d9e565b61120061024081610fc05e506110c05163d81f84b761122052600435611240526020611220602461123c845afa6126be573d5f5f3e3d5ffd5b3d602081183d602010021880611220016112401161579c57611220518060a01c61579c57611260525061126090505161120052610f8051604052610f205160605261120051608052610fe05160a0526110005160c05261271f6112406152db565b611240516112205261120051636f7af6f761126052610300806112805280611280015f610b40518083528060061b5f82600f811161579c57801561278257905b8060061b610b60018160061b6020880101604082825e505060010181811861275f575b50508201602001915050905081019050611220516112a052610f40516112c052336112e052610f605161130052610fa05161132052610240610fc06113405e5060206112606106e461127c5f855af16127dd573d5f5f3e3d5ffd5b60203d1061579c57611260905051611240525f61012052610f405161014052600161016052610240610fc06101805e612814614798565b60206112405f5f5df35b33610b40526001610b6052612867565b6004358060a01c61579c57610b40526001610b6052612867565b6004358060a01c61579c57610b40526024358060011c61579c57610b60525b5f5c60011461579c5760015f5d5f5461579c57610240366106c03761288d610dc0613d9e565b610dc061024081610b805e50610d805163182f3029610de052610b4051610e005233610e2052610b6051610e4052610240610b80610e605e6020610de06102a4610dfc5f855af16128e0573d5f5f3e3d5ffd5b60203d1061579c57610de0905051610dc0525f61012052610b405161014052600161016052610240610b806101805e612917614798565b6020610dc05f5f5df35b6001610e805261293c565b6024358060011c61579c57610e80525b600435600401601981351161579c5780355f816019811161579c57801561298557905b8060051b6020850101358060a01c61579c578160051b610b60015260010181811861295f575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376129b46110e0613d9e565b6110e061024081610ea05e506110a05163c7701b07611100526102a0806111205280611120015f610b40518083528060051b5f826019811161579c578015612a1657905b8060051b610b6001518160051b6020880101526001018181186129f8575b505082016020019150509050810190503361114052610e805161116052610240610ea06111805e5060206111006105e461111c5f855af1612a59573d5f5f3e3d5ffd5b60203d1061579c576111009050516110e0525f610120523361014052600161016052610240610ea06101805e612a8d614798565b60206110e05f5f5df35b33610e6052612ab1565b6064358060a01c61579c57610e60525b6004358060a01c61579c57610e40525f5461579c57610240366106c037612ad96110c0613d9e565b6110c061024081610e805e5033610e605114612b3f5733604052610f2051606052612b056110c06154b9565b6110c051612b3657610e6051610120523361014052610f205161016052612b2d6110e06142ac565b6110e051612b39565b60015b1561579c575b6020610e40516107405260243561076052610e6051610780525f6107a05260026107c052336107e052604435610800526001610820525f61084052600161086052610240610e806108805e612b956110c0614a14565b6110c0f35b33610b6052612bb4565b6044358060a01c61579c57610b60525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612be9610dc0613d9e565b610dc061024081610b805e50610c805163d81f84b7610de0526002610e00526020610de06024610dfc845afa612c21573d5f5f3e3d5ffd5b3d602081183d602010021880610de001610e001161579c57610de0518060a01c61579c57610e205250610e20905051610dc05233610b605114612cae5733604052610c2051606052612c74610de06154b9565b610de051612ca557610b6051610120523361014052610c205161016052612c9c610e006142ac565b610e0051612ca8565b60015b1561579c575b610dc05163068b62d0610de052610b6051610e0052610b4051610e2052602435610e4052610240610b80610e605e803b1561579c575f610de06102a4610dfc5f855af1612cfd573d5f5f3e3d5ffd5b505f61012052610b605161014052600161016052610240610b806101805e612d23614798565b5f5f5d005b33610b6052612d42565b6024358060a01c61579c57610b60525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612d77610dc0613d9e565b610dc061024081610b805e50610c805163d81f84b7610de0526002610e00526020610de06024610dfc845afa612daf573d5f5f3e3d5ffd5b3d602081183d602010021880610de001610e001161579c57610de0518060a01c61579c57610e205250610e20905051610dc05233610b605114612e3c5733604052610c2051606052612e02610de06154b9565b610de051612e3357610b6051610120523361014052610c205161016052612e2a610e006142ac565b610e0051612e36565b60015b1561579c575b610dc051636787bc2e610de052610b6051610e0052610b4051610e2052610240610b80610e405e803b1561579c575f610de0610284610dfc5f855af1612e84573d5f5f3e3d5ffd5b505f61012052610b605161014052600161016052610240610b806101805e612eaa614798565b5f5f5d005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b60525f610b805233610ba052612f23565b602435610b60525f610b805233610ba052612f23565b60406024610b603733610ba052612f23565b60406024610b60376064358060a01c61579c57610ba0525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612f58610e00613d9e565b610e0061024081610bc05e50610b6051610b40516370a08231610e205233610e40526020610e206024610e3c845afa612f93573d5f5f3e3d5ffd5b60203d1061579c57610e2090505180828118828410021890509050610e0052610b40516323b872dd610e205233610e4052610d4051610e6052610e0051610e80526020610e206064610e3c5f855af1612fee573d5f5f3e3d5ffd5b3d61300557803b1561579c576001610ea05261302f565b3d602081183d602010021880610e2001610e401161579c57610e20518060011c61579c57610ea052505b610ea09050511561579c57610d405163c691ea76610e4052610ba051610e6052610b4051610e8052610e0051610ea052610b8051610ec05233610ee052610240610bc0610f005e6020610e406102e4610e5c5f855af1613091573d5f5f3e3d5ffd5b60203d1061579c57610e40905051610e20525f61012052610ba05161014052600161016052610240610bc06101805e6130c8614798565b6020610e205f5f5df35b33610200526001610220526001610240526001610260526131b8565b6004358060a01c61579c57610200526001610220526001610240526001610260526131b8565b6004358060a01c61579c57610200526024358060011c61579c57610220526001610240526001610260526131b8565b6004358060a01c61579c57610200526024358060011c61579c57610220526044358060011c61579c57610240526001610260526131b8565b6004358060a01c61579c57610200526024358060011c61579c57610220526044358060011c61579c57610240526064358060011c61579c57610260525b5f5461579c576131c96102a0615639565b6102a05161028052336102005114613205576102005161012052336101405261028051610160526131fb6102a06142ac565b6102a0511561579c575b602060a061020060405e61321a6102a0615695565b6102a0f35b336102a05260016102c05260016102e052600161030052600161032052613373565b6024358060a01c61579c576102a05260016102c05260016102e052600161030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c05260016102e052600161030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c0526064358060011c61579c576102e052600161030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c0526064358060011c61579c576102e0526084358060011c61579c5761030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c0526064358060011c61579c576102e0526084358060011c61579c576103005260a4358060011c61579c57610320525b6004358060a01c61579c57610280525f5461579c57610280511561579c576102a051610280511461579c576133a9610360615639565b6103605161034052336102a051146133ef576102a05161012052336101405261034051610160526133db6103606142ac565b610360511561579c5733610280511461579c575b602060e061028060405e613404610360615712565b610360f35b6004358060a01c61579c57610280526134236102c0615639565b6102c0516102a0526102a051613442575f6102c05260206102c06134f1565b61028051613459575f6102c05260206102c06134f1565b336040526102a05160605261346f6102c061418d565b6102c051613486575f6102e05260206102e06134f1565b3360405260016060526001608052600160a0526102a05160c0526134ab6102c0615695565b6102c05061028051604052336060526001608052600160a052600160c052600160e0526102a051610100526134e16102c0615712565b6102c05060016102c05260206102c05bf35b5f6102405261350d565b6044358060a01c61579c57610240525b6004358060a01c61579c57610200526024358060a01c61579c576102205261024051610260526102405161354f57613546610280615639565b61028051610260525b602060406102006101205e610260516101605261356d6102806142ac565b610280f35b5f5ffd5b6020615b6d604039604051815260405163d81f84b76060526001608052602060606024607c845afa6135aa573d5f5f3e3d5ffd5b3d602081183d60201002188060600160801161579c576060518060a01c61579c5760a0525060a0905051602082015260405163d81f84b760c052600260e052602060c0602460dc845afa613600573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c576101005250610100905051604082015260405163d81f84b7610120526003610140526020610120602461013c845afa61365c573d5f5f3e3d5ffd5b3d602081183d602010021880610120016101401161579c57610120518060a01c61579c576101605250610160905051606082015260405163d81f84b76101805260046101a0526020610180602461019c845afa6136bb573d5f5f3e3d5ffd5b3d602081183d602010021880610180016101a01161579c57610180518060a01c61579c576101c052506101c0905051608082015260405163d81f84b76101e05260056102005260206101e060246101fc845afa61371a573d5f5f3e3d5ffd5b3d602081183d6020100218806101e0016102001161579c576101e0518060a01c61579c57610220525061022090505160a082015260405163d81f84b7610240526006610260526020610240602461025c845afa613779573d5f5f3e3d5ffd5b3d602081183d602010021880610240016102601161579c57610240518060a01c61579c57610280525061028090505160c082015260405163d81f84b76102a05260076102c05260206102a060246102bc845afa6137d8573d5f5f3e3d5ffd5b3d602081183d6020100218806102a0016102c01161579c576102a0518060a01c61579c576102e052506102e090505160e082015260405163d81f84b7610300526008610320526020610300602461031c845afa613837573d5f5f3e3d5ffd5b3d602081183d602010021880610300016103201161579c57610300518060a01c61579c57610340525061034090505161010082015260405163d81f84b7610360526009610380526020610360602461037c845afa613897573d5f5f3e3d5ffd5b3d602081183d602010021880610360016103801161579c57610360518060a01c61579c576103a052506103a090505161012082015260405163d81f84b76103c052600a6103e05260206103c060246103dc845afa6138f7573d5f5f3e3d5ffd5b3d602081183d6020100218806103c0016103e01161579c576103c0518060a01c61579c57610400525061040090505161014082015260405163d81f84b761042052600b610440526020610420602461043c845afa613957573d5f5f3e3d5ffd5b3d602081183d602010021880610420016104401161579c57610420518060a01c61579c57610460525061046090505161016082015260405163d81f84b761048052600c6104a0526020610480602461049c845afa6139b7573d5f5f3e3d5ffd5b3d602081183d602010021880610480016104a01161579c57610480518060a01c61579c576104c052506104c090505161018082015260405163d81f84b76104e052600d6105005260206104e060246104fc845afa613a17573d5f5f3e3d5ffd5b3d602081183d6020100218806104e0016105001161579c576104e0518060a01c61579c5761052052506105209050516101a082015260405163d81f84b761054052600e610560526020610540602461055c845afa613a77573d5f5f3e3d5ffd5b3d602081183d602010021880610540016105601161579c57610540518060a01c61579c5761058052506105809050516101c082015260405163d81f84b76105a052600f6105c05260206105a060246105bc845afa613ad7573d5f5f3e3d5ffd5b3d602081183d6020100218806105a0016105c01161579c576105a0518060a01c61579c576105e052506105e09050516101e082015260405163d81f84b7610600526010610620526020610600602461061c845afa613b37573d5f5f3e3d5ffd5b3d602081183d602010021880610600016106201161579c57610600518060a01c61579c57610640525061064090505161020082015260405163d81f84b7610660526011610680526020610660602461067c845afa613b97573d5f5f3e3d5ffd5b3d602081183d602010021880610660016106801161579c57610660518060a01c61579c576106a052506106a090505161022082015250565b6020615b6d823950565b6020615b6d5f395f5163d81f84b7608052600660a052602060806024609c845afa613c06573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a01161579c576080518060a01c61579c5760c0525060c0905051606052606051613c43575f815250613c99565b606051632ba0309360805260405160a052602060806024609c845afa613c6b573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a01161579c576080518060011c61579c5760c0525060c09050518152505b565b60405115613cad576060511515613caf565b5f5b1561579c576060516370a0823160a0523060c052602060a0602460bc845afa613cda573d5f5f3e3d5ffd5b60203d1061579c5760a09050516080526080511561579c5760605163a9059cbb60a05260405160c05260805160e052602060a0604460bc5f855af1613d21573d5f5f3e3d5ffd5b3d613d3857803b1561579c57600161010052613d5f565b3d602081183d60201002188060a00160c01161579c5760a0518060011c61579c5761010052505b6101009050511561579c576040516060517fc2bfa18928a62b432789c9dda1f6bb4c519799a6b51f4dc2f74374e8f34207cf60805160a052602060a0a3565b6106c05115613db5576102406106c0825e50613dcc565b613dc0610900613576565b61090061024081835e50505b565b60403660e037606051613de45760805115613de6565b5f5b613ed15760805115613e775760a05163d81f84b761012052608051610140526020610120602461013c845afa613e1e573d5f5f3e3d5ffd5b3d602081183d602010021880610120016101401161579c57610120518060a01c61579c57610160525061016090505160e05260e0511561579c576080516101005260605115613f805760605160e0511861579c57613f80565b60605115613f805760a05163c4d9ba6361012052606051610140526020610120602461013c845afa613eab573d5f5f3e3d5ffd5b60203d1061579c5761012090505161010052610100511561579c5760605160e052613f80565b60c051631403184861012052604051610140526020610120602461013c845afa613efd573d5f5f3e3d5ffd5b60203d1061579c5761012090505161010052610100511561579c5760a05163d81f84b76101205261010051610140526020610120602461013c845afa613f45573d5f5f3e3d5ffd5b3d602081183d602010021880610120016101401161579c57610120518060a01c61579c57610160525061016090505160e05260e0511561579c575b60e051815261010051602082015250565b6020615b6d606039606051639693413060805260405160a052602060806024609c845afa613fc1573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a01161579c576080518060011c61579c5760c0525060c090505115613ffa57600181525061418b565b60605163d81f84b760a052600860c052602060a0602460bc845afa614021573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060a01c61579c5760e0525060e0905051608052608051156140ad57608051634756122d60a05260405160c052602060a0602460bc845afa61407e573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060011c61579c5760e0525060e09050516140af565b5f5b156140be57600181525061418b565b60605163d81f84b760c052600660e052602060c0602460dc845afa6140e5573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c57610100525061010090505160a05260a051156141755760a051632ba0309360c05260405160e052602060c0602460dc845afa614144573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060011c61579c576101005250610100905051614177565b5f5b1561418657600181525061418b565b5f8152505b565b606051631cfe78ba60a052602060a0600460bc845afa6141af573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060a01c61579c5760e0525060e09050516080526080516141ec575f8152506142aa565b60805163d81f84b760c052600160e052602060c0602460dc845afa614213573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c57610100525061010090505160a05260a051614252575f8152506142aa565b60a0516342af624e60c05260405160e052602060c0602460dc845afa61427a573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060011c61579c5761010052506101009050518152505b565b61012051604052610160516060526142c561018061418d565b610180516142d6575f81525061439e565b6101205163d34ddc056101a05260206101a060046101bc845afa6142fc573d5f5f3e3d5ffd5b3d602081183d6020100218806101a0016101c01161579c576101a0518060a01c61579c576101e052506101e09050516101805261018051614340575f81525061439e565b6101405161018051638da5cb5b6101a05260206101a060046101bc845afa61436a573d5f5f3e3d5ffd5b3d602081183d6020100218806101a0016101c01161579c576101a0518060a01c61579c576101e052506101e0905051148152505b565b606051196143d1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff815250614400565b5f60805260405160605111156143f95760605160405180820382811161579c57905090506080525b6080518152505b565b5f608052604051606051111561442a5760605160405180820382811161579c57905090506080525b608051815250565b6103405163969ea76d6104a052610260516104c052610200516104e05261024051610500526101406104a060646104bc845afa614471573d5f5f3e3d5ffd5b3d61014081183d610140100218806104a0016105e01161579c57806104a0016105e01161579c576104a0518060011c61579c57610600526104c0518060011c61579c57610620526104e0518060011c61579c5761064052610500518060011c61579c576106605260806105206106805e6105a0518060011c61579c57610700526105c05161072052506106009050610140816103605e50610360511561579c57610380511561579c576103a0511561579c576103c0511561579c576102a05160405261453e6104c0613f91565b6104c0516104a0526102c05161456b576102a051610240511461456557610460511561456d565b5f61456d565b5f5b156145af576104a0516145a65761024051610120526102a05161014052610340516101605261459d6104c06142ac565b6104c0516145a9565b60015b1561579c575b6102a0516104c0526102e051156145c657306104c0525b61022051610200516370a08231610500526104c051610520526020610500602461051c845afa6145f8573d5f5f3e3d5ffd5b60203d1061579c57610500905051808281188284100218905090506104e0526104e0511561579c576104a05115614635576104e051815250614796565b6102805163e1210e4f61058052610240516105a052610200516105c0526080610580604461059c845afa61466b573d5f5f3e3d5ffd5b3d608081183d608010021880610580016106001161579c5780610580016106001161579c57610580518060011c61579c576106205260606105a06106405e5061062090506080816105005e50610300516146d2576104405161032051101561579c576146e9565b610500516146e9576104205161052051101561579c575b610540516040526103e0516060526147026105a06143a0565b6105a05161058052610580511561579c576104e05161058051808281188284100218905090506104e05261056051604052610400516060526147456105c0614402565b6105c0516105a0526105a0511561579c576104e0516105a051808281188284100218905090506104e052610480516104e0516105405180820182811061579c57905090501061579c576104e0518152505b565b5f6103c0526102205163c9e4059c6103e05260206103e060046103fc845afa6147c3573d5f5f3e3d5ffd5b3d602081183d6020100218806103e0016104001161579c576103e0518060011c61579c576104205250610420905051156148295761012051614805575f614824565b610140516040526102205160605261481e61044061418d565b61044051155b6103c0525b6102005163222a390e6103e05261014051610400526103c05161042052803b1561579c575f6103e060446103fc5f855af1614866573d5f5f3e3d5ffd5b506102605163d81f84b7610400526002610420526020610400602461041c845afa614893573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060a01c61579c5761044052506104409050516103e0526103e05115614925576103e051637cdb0a4d610400526020610400600461041c5f855af16148f6573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060011c61579c57610440525061044050505b6101605115614a1257610120516149a3576103205163f355711d6104005261014051610420526102406101806104405e602061040061026461041c5f855af1614970573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060011c61579c5761068052506106805050614a12565b6103205163f355711d6104005261014051610420526102406101806104405e602061040061026461041c5f855af16149dd573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060011c61579c5761068052506106809050511561579c575b565b604036610ac037610740516040526107a0516060526107c0516080526109805160a0526109205160c052614a49610b00613dce565b610b00604081610b405e506040610b40610ac05e6109005163245a644c610b405261078051610b6052610ae051610b80526040610b406044610b5c845afa614a93573d5f5f3e3d5ffd5b3d604081183d604010021880610b4001610b801161579c5780610b4001610b801161579c57610b40518060011c61579c57610ba052610b6051610bc05250610ba09050604081610b005e5060606107406102005e610ae05161026052610ac051610280526107e0516102a05260406108206102c05e6040610b006103005e6109205161034052614b24610b60614432565b610b6051610b405261084051614bc457610740516323b872dd610b60526107e051610b8052610ac051610ba052610b4051610bc0526020610b606064610b7c5f855af1614b73573d5f5f3e3d5ffd5b3d614b8a57803b1561579c576001610be052614bb4565b3d602081183d602010021880610b6001610b801161579c57610b60518060011c61579c57610be052505b610be09050511561579c57614c48565b6107405163a9059cbb610b6052610ac051610b8052610b4051610ba0526020610b606044610b7c5f855af1614bfb573d5f5f3e3d5ffd5b3d614c1257803b1561579c576001610bc052614c3c565b3d602081183d602010021880610b6001610b801161579c57610b60518060011c61579c57610bc052505b610bc09050511561579c575b6108005115614cba57610ac0516385242616610b605261078051610b805261074051610ba052610b4051610bc05261080051610be052610240610880610c005e6020610b606102c4610b7c5f855af1614ca3573d5f5f3e3d5ffd5b60203d1061579c57610b60905051610b4052614d17565b610ac05163bfc78712610b605261078051610b805261074051610ba052610b4051610bc052610240610880610be05e6020610b606102a4610b7c5f855af1614d04573d5f5f3e3d5ffd5b60203d1061579c57610b60905051610b40525b610b0051614d5e576109005163c5bda89c610b605261078051610b8052610ae051610ba052803b1561579c575f610b606044610b7c5f855af1614d5c573d5f5f3e3d5ffd5b505b610a805163856ea3c6610b605261078051610b8052610ae051610ba052610ac051610bc05261074051610be052610240610880610c005e803b1561579c575f610b606102c4610b7c5f855af1614db6573d5f5f3e3d5ffd5b506108605115614de5575f6101205261078051610140526001610160526102406108806101805e614de5614798565b61096051635ad6a4b7610b605261074051610b80526020610b606024610b7c5f855af1614e14573d5f5f3e3d5ffd5b3d602081183d602010021880610b6001610b801161579c57610b60518060011c61579c57610ba05250610ba05050610740516107e051610780517ffea6f3dacc57406b0007933d492eb1d67328e5d55c8ede1fc213c6d63edca049610b4051610b6052610ac051610b8052610ae051610ba0526060610b60a4610b4051815250565b610220511561579c576102c0511561579c576102e0511561579c57610300511561579c576102a0516102405114614ed1576103205115614ed3565b5f5b15614f055761024051610120526102a051610140526104005161016052614efb6105a06142ac565b6105a0511561579c575b61050051634bd97a166105c052610240516105e0526102805161060052610200516106205261026051610640526102406103606106605e60206105c06102c46105dc845afa614f56573d5f5f3e3d5ffd5b60203d1061579c576105c09050516105a0526105a0511561579c57610220516105a05180828118828410021890509050815250565b604036610ba0376108a0516040526109005160605261092051608052610a605160a052610a005160c052614fc0610be0613dce565b610be0604081610c205e506040610c20610ba05e610a00516337f1a2b3610c80526108a051610ca0526108e051610cc05261094051610ce05260a0610c806064610c9c845afa615012573d5f5f3e3d5ffd5b3d60a081183d60a010021880610c8001610d201161579c5780610c8001610d201161579c57610c80518060011c61579c57610d4052610ca0518060011c61579c57610d6052610cc0518060011c61579c57610d8052610ce0518060011c61579c57610da052610d0051610dc05250610d40905060a081610be05e5060606108a06102005e6040610ba06102605e610940516102a05260a0610be06102c05e6102406109606103605e6150c5610ca0614e96565b610ca051610c80525f610ca052610ba05163402495a4610cc0526108e051610ce0526108a051610d0052610c8051610d20526108e051610d4052610240610960610d605e6040610cc06102c4610cdc5f855af1615124573d5f5f3e3d5ffd5b3d604081183d604010021880610cc001610d001161579c57610cc051610fa052610ce0518060011c61579c57610fc05250610fa09050604081610fe05e506040610fe0610c805e610ca0516151c957610ba0516396c3a427610ce0526108e051610d00526108a051610d20526020610ce06044610cfc845afa6151a9573d5f5f3e3d5ffd5b60203d1061579c57610ce0905051610cc052610c6051610cc0511061579c575b610b605163856ea3c6610cc0526108e051610ce052610bc051610d0052610ba051610d20526108a051610d4052610240610960610d605e803b1561579c575f610cc06102c4610cdc5f855af1615221573d5f5f3e3d5ffd5b50610a4051635ad6a4b7610cc0526108a051610ce0526020610cc06024610cdc5f855af1615251573d5f5f3e3d5ffd5b3d602081183d602010021880610cc001610ce01161579c57610cc0518060011c61579c57610d005250610d005050610940516108a0516108e0517f6b0d92ac92e3ebfdb54eaa7f092d7be054f8939df0c41f1c961f80fdb5d1e422610c8051610cc052610ba051610ce052610bc051610d0052610ca051610d20526080610cc0a4610c8051815250565b60a05160e052604051156152f05760c05160e0525b60605160e0516370a082316101205233610140526020610120602461013c845afa61531d573d5f5f3e3d5ffd5b60203d1061579c576101209050518082811882841002189050905061010052610100511561579c576080511561579c576040516153df5760a0516323b872dd6101205233610140526080516101605261010051610180526020610120606461013c5f855af161538e573d5f5f3e3d5ffd5b3d6153a557803b1561579c5760016101a0526153cf565b3d602081183d602010021880610120016101401161579c57610120518060011c61579c576101a052505b6101a09050511561579c576154b0565b60c0516323b872dd610120523361014052306101605261010051610180526020610120606461013c5f855af1615417573d5f5f3e3d5ffd5b3d61542e57803b1561579c5760016101a052615458565b3d602081183d602010021880610120016101401161579c57610120518060011c61579c576101a052505b6101a09050511561579c5760c05163ba0876526101205261010051610140526080516101605230610180526020610120606461013c5f855af161549d573d5f5f3e3d5ffd5b60203d1061579c57610120905051610100525b61010051815250565b606051631cfe78ba60a052602060a0600460bc845afa6154db573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060a01c61579c5760e0525060e0905051608052608051615518575f815250615637565b608051639693413060a05260405160c052602060a0602460bc845afa615540573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060011c61579c5760e0525060e090505115615579576001815250615637565b60805163d81f84b760c052600360e052602060c0602460dc845afa6155a0573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c57610100525061010090505160a05260a0516155df575f815250615637565b60a051639693413060c05260405160e052602060c0602460dc845afa615607573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060011c61579c5761010052506101009050518152505b565b6020615b6d5f395f5163d81f84b76040526005606052602060406024605c845afa615666573d5f5f3e3d5ffd5b3d602081183d60201002188060400160601161579c576040518060a01c61579c57608052506080905051815250565b6060606060e05e60c051636e6f30296101405260405161016052606060e06101805e803b1561579c575f610140608461015c5f855af16156d7573d5f5f3e3d5ffd5b50336040517fa1df7ba437478e42ba351e23d5875bc241b38d2f42357ce394db3831110d9fc7606060606101405e6060610140a36001815250565b608060806101205e6101005163fac3ef616101a0526060516101c0526040516101e05260806101206102005e803b1561579c575f6101a060c46101bc5f855af161575e573d5f5f3e3d5ffd5b50336040516060517fe57f0d8a88a7e27cf4de7394d7913a3c69cdc3a26b5d956d55c8abe3d9f04271608060806101a05e60806101a0a46001815250565b5f80fd000a5ac50500b259b50605df5a5508000f5aed0600085b1d031cce587d0e001759250500a75a250600065b5d02000d58ed07014459e50800b75a950601d457f50800195b350500a5594d0707825835090035598506a5c7434a00640005b8b419741306002587a5b71618030045dfcd412e07180085b187bd260210000536b20ad41e070065205f940930ee00252fe0f37f0b8d0065246f9d992a97006509b9f55600770005225b962e105000659d361ff93409002524ae6a27010800458785beba292c0045d4c21c8e182100655501f1c6074700a540fd6f940087000569328dec06f6006534146458326d00653b6fccc0009500057dd5da70251f0085b30420f9155d0065d1c469162d28002553992db72b9a00452ef838b632410045f45346dc02690065843fdaee1e5100a551cff8d906a80025371fd8e60b4b0025f813ce6e0dbc00e5dd74b3102aa1008502329a2900a30025f412e5e818bf00c564505a3e22cb00c5bdc62a7c13110045b206b9c932a20085958c288b31430065a321c62804db02e53fb7de5202ba00a594863d361b060025e64fe31f1e7100c57053a18f01500045556bfd9c0d0200658d5c9efc13e70025cf29e4c9321f00253969c94c24c500452f2800831e3b00853dcbe8600d5c00a5f340fa01021b0025758289482eaf00254567d2d41655010547e7ef240251004581c63a8d15b700a54edab157081000459ab7eb6b226e0085be6979e520090085b1e168382ef90065f0ae528629210025f74ade6830d2000571b78d170dfa0105c5ebeaec09b00025c6f1649f028b00858dc17754317b00852cf0fd552f0b008556cc9045188100a5cfca23190d8700c55481c8c017c70025025699f503620045f29c9f631ff00065acb708150b670045db33279d34fd0065815a439228480045db89bf5904ce00a5c9a6eea7281e000591774d06159900858b8a23890d3e0085b7097b4e282e0025263fe583230a00e56bc67a221fe10045402d88830b110005c7c77bb22ee30045f3fef3a306de0045ce6442592ba40065e68d3569097600054b3fd14809cc0045897b357b0bbd008557d094c5184c00858b655a370a2100853ea63e8134f30045ea5bda9413f20045918c344709f20065c721198632e000a52cc7d2e3254700a506dfaff2257c00c574ff30f410320045eba2073a10b000a561484d1d311400454a9186b10ff600255fd76b71332700c5c0ac867515e200c579942b961ad700050128d538107b00854fa3d65c161700e59401e3ac1b3f00451768d1cc250100656a0ac6c0229600a59cb2b0622d32004560f23e3725bb00e5c5f7de4e10ee00c5a9d12127221400452febc58d22500065855820ce8e11625a55fed07235940978abc34a76106c0bd0b7b22ec46c377b9d7f824d195b6d9218551840184818701838182818381830183018401830184018301828183018181828101860a16576797065728300040300590000000000000000000000006162df1b329e157479f8f1407e888260e0ec3d2b0000000000000000000000000000000000000000000000000000000000000001

Deployed Bytecode

0x5f3560e01c6005600560118306026157a001601b395f5160088160ff16838360181c0260181c0660031b8260081c61ffff1601601839505f51818160201c14600336111615613572578061fffe1636103482600116021761579c578060101c61ffff16565b6102406100726106c0613576565b6106c0f35b60206100836040613bcf565b6040f35b6020615b8d60403960206040f35b6020615bad60403960206040f35b6004358060011c61579c5760e052336040526100c0610100613bd9565b610100511561579c575f5460e0511461579c5760e0515f557fdd3e5b8936c85b0f24d27616bb5cd2bc155c70d2d372e734a6e1a5be777acd9b60e051610100526020610100a1005b6004358060a01c61579c57610120526024358060a01c61579c576101405233604052610135610160613bd9565b610160511561579c57604061012060405e61014e613c9b565b005b6004358060a01c61579c5761012052602435600401601481351161579c5780355f816014811161579c5780156101a857905b8060051b6020850101358060a01c61579c578160051b6101600152600101818118610182575b505080610140525050336040526101c06103e0613bd9565b6103e0511561579c575f610140516014811161579c57801561020c57905b8060051b61016001516103e052610120516040526103e051606052610201613c9b565b6001018181186101de575b5050005b5f5460405260206040f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e605233610e8052604036610ea0376102e7565b602435610e605233610e8052604036610ea0376102e7565b602435610e60526044358060a01c61579c57610e8052604036610ea0376102e7565b602435610e60526044358060a01c61579c57610e80526064358060a01c61579c57610ea0525f610ec0526102e7565b602435610e60526044358060a01c61579c57610e80526064358060a01c61579c57610ea052608435610ec0525b6004358060a01c61579c57610e40525f5c60011461579c5760015f5d5f5461579c57610240366106c03761031c611120613d9e565b61112061024081610ee05e50602060a0610e406107405e336107e05260603661080037600161086052610240610ee06108805e61035a611120614a14565b6111205f5f5df35b6004358060a01c61579c57610e4052602435600401601481351161579c5780355f816014811161579c5780156103e457905b8060071b60208501018160071b610e800181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118610394575b505080610e605250505f5c60011461579c5760015f5d5f5461579c57610240366106c037610413611ac0613d9e565b611ac0610240816118805e505f610e60516014811161579c57801561049557905b8060071b610e8001608081611ac05e506040611ac06107405e610e405161078052611b00516107a052611b20516107c052336107e052608036610800376102406118806108805e610486611b40614a14565b611b4050600101818118610434575b50505f61012052610e4051610140526001610160526102406118806101805e6104bc614798565b610e6051611ac0526020611ac05f5f5df35b61024036610e80376105f9565b60a4358060a01c61579c57610e805260c4358060a01c61579c57610ea05260e4358060a01c61579c57610ec052610104358060a01c61579c57610ee052610124358060a01c61579c57610f0052610144358060a01c61579c57610f2052610164358060a01c61579c57610f4052610184358060a01c61579c57610f60526101a4358060a01c61579c57610f80526101c4358060a01c61579c57610fa0526101e4358060a01c61579c57610fc052610204358060a01c61579c57610fe052610224358060a01c61579c5761100052610244358060a01c61579c5761102052610264358060a01c61579c5761104052610284358060a01c61579c57611060526102a4358060a01c61579c57611080526102c4358060a01c61579c576110a0525b6004358060a01c61579c57610e40526044358060a01c61579c57610e6052336040526106266110c0613f91565b6110c0511561579c57610240610e806106c05e610644611300613d9e565b611300610240816110c05e506020610e60516107405260643561076052610e4051610780525f6107a0526024356107c052336107e05260843561080052600161082052604036610840376102406110c06108805e6106a3611300614a14565b611300f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61104052336110605260403661108037610774565b60243561104052336110605260403661108037610774565b602435611040526044358060a01c61579c576110605260403661108037610774565b602435611040526044358060a01c61579c57611060526064358060a01c61579c57611080525f6110a052610774565b602435611040526044358060a01c61579c57611060526064358060a01c61579c57611080526084356110a0525b6004358060a01c61579c57611020525f5c60011461579c5760015f5d5f5461579c57610240366106c0376107a9611300613d9e565b611300610240816110c05e5060a06110206108a05e33610940526102406110c06109605e6107d8611320614f8b565b611320516113005260016101205261106051610140526001610160526102406110c06101805e610806614798565b60206113005f5f5df35b6004358060a01c61579c5761102052602435600401601481351161579c5780355f816014811161579c57801561089257905b8060071b60208501018160071b6110600181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118610842575b5050806110405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376108c1611ca0613d9e565b611ca061024081611a605e505f611040516014811161579c57801561093c57905b8060071b61106001608081611ca05e506040611ca06108a05e611020516108e052611ce05161090052611d0051610920523361094052610240611a606109605e61092d611d20614f8b565b611d20506001018181186108e2575b50506001610120526110205161014052600161016052610240611a606101805e610964614798565b61104051611ca0526020611ca05f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b405233610b60526001610b80525f610ba052610a56565b600435610b405233610b60526001610b80525f610ba052610a56565b600435610b40526024358060a01c61579c57610b60526001610b80525f610ba052610a56565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80525f610ba052610a56565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80526064358060011c61579c57610ba0525b5f5c60011461579c5760015f5d5f5461579c57610240366106c037610a7c610e00613d9e565b610e0061024081610bc05e50600161012052610b6051610140525f61016052610240610bc06101805e610aad614798565b6020610d60516357b13c7f610e0052610b6051610e2052610b4051610e40526040610b80610e605e33610ea052610240610bc0610ec05e6020610e006102e4610e1c5f855af1610aff573d5f5f3e3d5ffd5b60203d1061579c57610e0090505f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b405233610b60525f610b80526001610ba052610bf2565b600435610b405233610b60525f610b80526001610ba052610bf2565b600435610b40526024358060a01c61579c57610b60525f610b80526001610ba052610bf2565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80526001610ba052610bf2565b600435610b40526024358060a01c61579c57610b60526044358060011c61579c57610b80526064358060011c61579c57610ba0525b5f5c60011461579c5760015f5d5f5461579c57610240366106c037610c18610e00613d9e565b610e0061024081610bc05e505f61012052610b6051610140525f61016052610240610bc06101805e610c48614798565b610b8051604052610b4051606052610d6051608052610be05160a052610c005160c052610c76610e206152db565b610e2051610e00526020610d605163d2302444610e2052610b6051610e4052610e0051610e6052610ba051610e805233610ea052610240610bc0610ec05e6020610e206102c4610e3c5f855af1610ccf573d5f5f3e3d5ffd5b3d602081183d602010021880610e2001610e401161579c57610e20518060011c61579c57611100525061110090505f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b8052604036610ba0376001610be05233610c0052610e3e565b606435610b8052604036610ba0376001610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba0525f610bc0526001610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc0526001610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05233610c0052610e3e565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05260e4358060a01c61579c57610c00525b6004358060a01c61579c57610b40526044358060a01c61579c57610b60525f5c60011461579c5760015f5d5f5461579c57610240366106c037610e82610e60613d9e565b610e6061024081610c205e50610ba051604052610b8051606052610dc051608052610c405160a052610c605160c052610ebc610e806152db565b610e8051610e6052610b4051610ea052602435610ec052610b6051610ee052610e6051610f00526001610e8052610dc051632ca47d996118c052610300806118e052806118e0015f610e80518083528060071b5f826014811161579c578015610f4457905b8060071b610ea0018160071b6020880101608082825e5050600101818118610f21575b505082016020019150509050810190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61190052610c00516119205233611940526040610bc06119605e610240610c206119a05e5060206118c0610d246118dc5f855af1610fb5573d5f5f3e3d5ffd5b60203d1061579c576118c09050516118a0525f61012052610c005161014052600161016052610240610c206101805e610fec614798565b60206118a05f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611560526040366115803760016115c052336115e052611132565b602435611560526040366115803760016115c052336115e052611132565b602435611560526044358060011c61579c57611580525f6115a05260016115c052336115e052611132565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a05260016115c052336115e052611132565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c052336115e052611132565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c05260a4358060a01c61579c576115e0525b600435600401601481351161579c5780355f816014811161579c5780156111a557905b8060071b60208501018160071b610b600181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118611155575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376111d4611840613d9e565b611840610240816116005e5061158051604052611560516060526117a0516080526116205160a0526116405160c05261120e6118606152db565b61186051611840526117a051632ca47d9961188052610300806118a052806118a0015f610b40518083528060071b5f826014811161579c57801561127157905b8060071b610b60018160071b6020880101608082825e505060010181811861124e575b50508201602001915050905081019050611840516118c0526115e0516118e052336119005260406115a06119205e6102406116006119605e506020611880610d2461189c5f855af16112c5573d5f5f3e3d5ffd5b60203d1061579c57611880905051611860525f610120526115e051610140526001610160526102406116006101805e6112fc614798565b60206118605f5f5df35b6001610b6052611321565b6024358060011c61579c57610b60525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037611356610dc0613d9e565b610dc061024081610b805e50610ca05163c36746b4610de052610b4051610e005233610e2052610b6051610e4052610240610b80610e605e6020610de06102a4610dfc5f855af16113a9573d5f5f3e3d5ffd5b60203d1061579c57610de0905051610dc0525f610120523361014052600161016052610240610b806101805e6113dd614798565b6020610dc05f5f5df35b60016111a052611402565b6024358060011c61579c576111a0525b600435600401603281351161579c5780355f816032811161579c57801561144b57905b8060051b6020850101358060a01c61579c578160051b610b600152600101818118611425575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c03761147a611400613d9e565b611400610240816111c05e506112e0516336caaa9d611420526102a0806114405280611440015f610b40518083528060051b5f826032811161579c5780156114dc57905b8060051b610b6001518160051b6020880101526001018181186114be575b5050820160200191505090508101905033611460526111a051611480526102406111c06114a05e50602061142061090461143c5f855af161151f573d5f5f3e3d5ffd5b60203d1061579c57611420905051611400525f6101205233610140526001610160526102406111c06101805e611553614798565b60206114005f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b8052604036610ba0376001610be05233610c0052611699565b606435610b8052604036610ba0376001610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba0525f610bc0526001610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc0526001610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05233610c0052611699565b606435610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be05260e4358060a01c61579c57610c00525b6004358060a01c61579c57610b40526044358060a01c61579c57610b60525f5c60011461579c5760015f5d5f5461579c57610240366106c0376116dd610e60613d9e565b610e6061024081610c205e50610ba051604052610b8051606052610d4051608052610c405160a052610c605160c052611717610e806152db565b610e8051610e6052610d4051636dce8d20610ea052610b4051610ec052602435610ee052610b6051610f0052610e6051610f2052610c0051610f405233610f60526040610bc0610f805e610240610c20610fc05e6020610ea0610344610ebc5f855af1611786573d5f5f3e3d5ffd5b60203d1061579c57610ea0905051610e80525f61012052610c005161014052600161016052610240610c206101805e6117bd614798565b6020610e805f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611560526040366115803760016115c052336115e052611903565b602435611560526040366115803760016115c052336115e052611903565b602435611560526044358060011c61579c57611580525f6115a05260016115c052336115e052611903565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a05260016115c052336115e052611903565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c052336115e052611903565b602435611560526044358060011c61579c57611580526064358060011c61579c576115a0526084358060011c61579c576115c05260a4358060a01c61579c576115e0525b600435600401601481351161579c5780355f816014811161579c57801561197657905b8060071b60208501018160071b610b600181358060a01c61579c5781526020820135602082015260408201358060a01c61579c576040820152606082013560608201525050600101818118611926575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376119a5611840613d9e565b611840610240816116005e506115805160405261156051606052611720516080526116205160a0526116405160c0526119df6118606152db565b61186051611840526117205163896c6d1461188052610300806118a052806118a0015f610b40518083528060071b5f826014811161579c578015611a4257905b8060071b610b60018160071b6020880101608082825e5050600101818118611a1f575b50508201602001915050905081019050611840516118c0526115e0516118e052336119005260406115a06119205e6102406116006119605e506020611880610d2461189c5f855af1611a96573d5f5f3e3d5ffd5b60203d1061579c57611880905051611860525f610120526115e051610140526001610160526102406116006101805e611acd614798565b60206118605f5f5df35b33610e40527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e6052611b56565b6004358060a01c61579c57610e40527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e6052611b56565b6004358060a01c61579c57610e4052602435610e60525b5f5c60011461579c5760015f5d5f5461579c57610240366106c037611b7c6110c0613d9e565b6110c061024081610e805e50610e6051610ea0516370a082316110e052336111005260206110e060246110fc845afa611bb7573d5f5f3e3d5ffd5b60203d1061579c576110e0905051808281188284100218905090506110c0526110c0511561579c57610ea0516323b872dd6110e052336111005230611120526110c0516111405260206110e060646110fc5f855af1611c18573d5f5f3e3d5ffd5b3d611c2f57803b1561579c57600161116052611c59565b3d602081183d6020100218806110e0016111001161579c576110e0518060011c61579c5761116052505b6111609050511561579c57610ea05163095ea7b36110e052610ec051611100526110c0516111205260206110e060446110fc5f855af1611c9b573d5f5f3e3d5ffd5b3d611cb257803b1561579c57600161114052611cdc565b3d602081183d6020100218806110e0016111001161579c576110e0518060011c61579c5761114052505b6111409050511561579c57610ec051636e553f65611100526110c0516111205230611140526020611100604461111c5f855af1611d1b573d5f5f3e3d5ffd5b60203d1061579c576111009050516110e052610ea05163095ea7b361110052610ec051611120525f611140526020611100604461111c5f855af1611d61573d5f5f3e3d5ffd5b3d611d7857803b1561579c57600161116052611da2565b3d602081183d602010021880611100016111201161579c57611100518060011c61579c5761116052505b6111609050511561579c576020610ec051610740526110e05161076052610e4051610780525f6107a05260016107c052336107e05260403661080037600161084052600161086052610240610e806108805e611dff611100614a14565b6111005f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b805233610ba0525f610bc052611e97565b606435610b805233610ba0525f610bc052611e97565b606435610b80526084358060a01c61579c57610ba0525f610bc052611e97565b606435610b80526084358060a01c61579c57610ba05260a4358060011c61579c57610bc0525b6024358060a01c61579c57610b40526044358060a01c61579c57610b60525f5c60011461579c5760015f5d5f5461579c57610240366106c037611edb610e20613d9e565b610e2061024081610be05e50610ce05163d81f84b7610e4052600435610e60526020610e406024610e5c845afa611f14573d5f5f3e3d5ffd5b3d602081183d602010021880610e4001610e601161579c57610e40518060a01c61579c57610e805250610e80905051610e2052610e20516348b62d4e610e6052610ba051610e8052610b4051610ea0526040610b60610ec05e33610f0052610bc051610f2052610240610be0610f405e6020610e60610304610e7c5f855af1611f9f573d5f5f3e3d5ffd5b60203d1061579c57610e60905051610e4052600161012052610ba05161014052600161016052610240610be06101805e611fd7614798565b6020610e405f5f5df35b33611100525f61112052612028565b6044358060a01c61579c57611100525f61112052612028565b6044358060a01c61579c57611100526064358060011c61579c57611120525b602435600401600f81351161579c5780355f81600f811161579c57801561209157905b60608102602085010160608202610b600181358060a01c61579c57815260208201358060a01c61579c57602082015260408201356040820152505060010181811861204b575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376120c0611380613d9e565b611380610240816111405e506112405163d81f84b76113a0526004356113c05260206113a060246113bc845afa6120f9573d5f5f3e3d5ffd5b3d602081183d6020100218806113a0016113c01161579c576113a0518060a01c61579c576113e052506113e0905051611380526113805163fb0163a26113c0526102c0611100516113e0528061140052806113e0015f610b4051808352606081025f82600f811161579c57801561218f57905b60608102610b6001606082026020880101606082825e505060010181811861216c575b50508201602001915050905081019050336114205261112051611440526102406111406114605e5060206113c06108846113dc5f855af16121d2573d5f5f3e3d5ffd5b60203d1061579c576113c09050516113a05260016101205261110051610140526001610160526102406111406101805e61220a614798565b60206113a05f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b605233610b8052604036610ba0376001610be05261234e565b604435610b605233610b8052604036610ba0376001610be05261234e565b604435610b60526064358060a01c61579c57610b8052604036610ba0376001610be05261234e565b604435610b60526064358060a01c61579c57610b80526084358060011c61579c57610ba0525f610bc0526001610be05261234e565b604435610b60526064358060a01c61579c57610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc0526001610be05261234e565b604435610b60526064358060a01c61579c57610b80526084358060011c61579c57610ba05260a4358060011c61579c57610bc05260c4358060011c61579c57610be0525b6024358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612383610e40613d9e565b610e4061024081610c005e50610d005163d81f84b7610e6052600435610e80526020610e606024610e7c845afa6123bc573d5f5f3e3d5ffd5b3d602081183d602010021880610e6001610e801161579c57610e60518060a01c61579c57610ea05250610ea0905051610e4052610bc051604052610b6051606052610e4051608052610c205160a052610c405160c05261241d610e806152db565b610e8051610e6052610e405163ce566e1d610ea052610b4051610ec052610e6051610ee052610b8051610f005233610f2052610ba051610f4052610be051610f6052610240610c00610f805e6020610ea0610304610ebc5f855af1612484573d5f5f3e3d5ffd5b60203d1061579c57610ea0905051610e80525f61012052610b805161014052600161016052610240610c006101805e6124bb614798565b6020610e805f5f5df35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610f205233610f4052604036610f60376001610fa0526125ff565b604435610f205233610f4052604036610f60376001610fa0526125ff565b604435610f20526064358060a01c61579c57610f4052604036610f60376001610fa0526125ff565b604435610f20526064358060a01c61579c57610f40526084358060011c61579c57610f60525f610f80526001610fa0526125ff565b604435610f20526064358060a01c61579c57610f40526084358060011c61579c57610f605260a4358060011c61579c57610f80526001610fa0526125ff565b604435610f20526064358060a01c61579c57610f40526084358060011c61579c57610f605260a4358060011c61579c57610f805260c4358060011c61579c57610fa0525b602435600401600f81351161579c5780355f81600f811161579c57801561265657905b8060061b60208501018160061b610b600181358060a01c61579c578152602082013560208201525050600101818118612622575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c037612685611200613d9e565b61120061024081610fc05e506110c05163d81f84b761122052600435611240526020611220602461123c845afa6126be573d5f5f3e3d5ffd5b3d602081183d602010021880611220016112401161579c57611220518060a01c61579c57611260525061126090505161120052610f8051604052610f205160605261120051608052610fe05160a0526110005160c05261271f6112406152db565b611240516112205261120051636f7af6f761126052610300806112805280611280015f610b40518083528060061b5f82600f811161579c57801561278257905b8060061b610b60018160061b6020880101604082825e505060010181811861275f575b50508201602001915050905081019050611220516112a052610f40516112c052336112e052610f605161130052610fa05161132052610240610fc06113405e5060206112606106e461127c5f855af16127dd573d5f5f3e3d5ffd5b60203d1061579c57611260905051611240525f61012052610f405161014052600161016052610240610fc06101805e612814614798565b60206112405f5f5df35b33610b40526001610b6052612867565b6004358060a01c61579c57610b40526001610b6052612867565b6004358060a01c61579c57610b40526024358060011c61579c57610b60525b5f5c60011461579c5760015f5d5f5461579c57610240366106c03761288d610dc0613d9e565b610dc061024081610b805e50610d805163182f3029610de052610b4051610e005233610e2052610b6051610e4052610240610b80610e605e6020610de06102a4610dfc5f855af16128e0573d5f5f3e3d5ffd5b60203d1061579c57610de0905051610dc0525f61012052610b405161014052600161016052610240610b806101805e612917614798565b6020610dc05f5f5df35b6001610e805261293c565b6024358060011c61579c57610e80525b600435600401601981351161579c5780355f816019811161579c57801561298557905b8060051b6020850101358060a01c61579c578160051b610b60015260010181811861295f575b505080610b405250505f5c60011461579c5760015f5d5f5461579c57610240366106c0376129b46110e0613d9e565b6110e061024081610ea05e506110a05163c7701b07611100526102a0806111205280611120015f610b40518083528060051b5f826019811161579c578015612a1657905b8060051b610b6001518160051b6020880101526001018181186129f8575b505082016020019150509050810190503361114052610e805161116052610240610ea06111805e5060206111006105e461111c5f855af1612a59573d5f5f3e3d5ffd5b60203d1061579c576111009050516110e0525f610120523361014052600161016052610240610ea06101805e612a8d614798565b60206110e05f5f5df35b33610e6052612ab1565b6064358060a01c61579c57610e60525b6004358060a01c61579c57610e40525f5461579c57610240366106c037612ad96110c0613d9e565b6110c061024081610e805e5033610e605114612b3f5733604052610f2051606052612b056110c06154b9565b6110c051612b3657610e6051610120523361014052610f205161016052612b2d6110e06142ac565b6110e051612b39565b60015b1561579c575b6020610e40516107405260243561076052610e6051610780525f6107a05260026107c052336107e052604435610800526001610820525f61084052600161086052610240610e806108805e612b956110c0614a14565b6110c0f35b33610b6052612bb4565b6044358060a01c61579c57610b60525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612be9610dc0613d9e565b610dc061024081610b805e50610c805163d81f84b7610de0526002610e00526020610de06024610dfc845afa612c21573d5f5f3e3d5ffd5b3d602081183d602010021880610de001610e001161579c57610de0518060a01c61579c57610e205250610e20905051610dc05233610b605114612cae5733604052610c2051606052612c74610de06154b9565b610de051612ca557610b6051610120523361014052610c205161016052612c9c610e006142ac565b610e0051612ca8565b60015b1561579c575b610dc05163068b62d0610de052610b6051610e0052610b4051610e2052602435610e4052610240610b80610e605e803b1561579c575f610de06102a4610dfc5f855af1612cfd573d5f5f3e3d5ffd5b505f61012052610b605161014052600161016052610240610b806101805e612d23614798565b5f5f5d005b33610b6052612d42565b6024358060a01c61579c57610b60525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612d77610dc0613d9e565b610dc061024081610b805e50610c805163d81f84b7610de0526002610e00526020610de06024610dfc845afa612daf573d5f5f3e3d5ffd5b3d602081183d602010021880610de001610e001161579c57610de0518060a01c61579c57610e205250610e20905051610dc05233610b605114612e3c5733604052610c2051606052612e02610de06154b9565b610de051612e3357610b6051610120523361014052610c205161016052612e2a610e006142ac565b610e0051612e36565b60015b1561579c575b610dc051636787bc2e610de052610b6051610e0052610b4051610e2052610240610b80610e405e803b1561579c575f610de0610284610dfc5f855af1612e84573d5f5f3e3d5ffd5b505f61012052610b605161014052600161016052610240610b806101805e612eaa614798565b5f5f5d005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610b60525f610b805233610ba052612f23565b602435610b60525f610b805233610ba052612f23565b60406024610b603733610ba052612f23565b60406024610b60376064358060a01c61579c57610ba0525b6004358060a01c61579c57610b40525f5c60011461579c5760015f5d5f5461579c57610240366106c037612f58610e00613d9e565b610e0061024081610bc05e50610b6051610b40516370a08231610e205233610e40526020610e206024610e3c845afa612f93573d5f5f3e3d5ffd5b60203d1061579c57610e2090505180828118828410021890509050610e0052610b40516323b872dd610e205233610e4052610d4051610e6052610e0051610e80526020610e206064610e3c5f855af1612fee573d5f5f3e3d5ffd5b3d61300557803b1561579c576001610ea05261302f565b3d602081183d602010021880610e2001610e401161579c57610e20518060011c61579c57610ea052505b610ea09050511561579c57610d405163c691ea76610e4052610ba051610e6052610b4051610e8052610e0051610ea052610b8051610ec05233610ee052610240610bc0610f005e6020610e406102e4610e5c5f855af1613091573d5f5f3e3d5ffd5b60203d1061579c57610e40905051610e20525f61012052610ba05161014052600161016052610240610bc06101805e6130c8614798565b6020610e205f5f5df35b33610200526001610220526001610240526001610260526131b8565b6004358060a01c61579c57610200526001610220526001610240526001610260526131b8565b6004358060a01c61579c57610200526024358060011c61579c57610220526001610240526001610260526131b8565b6004358060a01c61579c57610200526024358060011c61579c57610220526044358060011c61579c57610240526001610260526131b8565b6004358060a01c61579c57610200526024358060011c61579c57610220526044358060011c61579c57610240526064358060011c61579c57610260525b5f5461579c576131c96102a0615639565b6102a05161028052336102005114613205576102005161012052336101405261028051610160526131fb6102a06142ac565b6102a0511561579c575b602060a061020060405e61321a6102a0615695565b6102a0f35b336102a05260016102c05260016102e052600161030052600161032052613373565b6024358060a01c61579c576102a05260016102c05260016102e052600161030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c05260016102e052600161030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c0526064358060011c61579c576102e052600161030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c0526064358060011c61579c576102e0526084358060011c61579c5761030052600161032052613373565b6024358060a01c61579c576102a0526044358060011c61579c576102c0526064358060011c61579c576102e0526084358060011c61579c576103005260a4358060011c61579c57610320525b6004358060a01c61579c57610280525f5461579c57610280511561579c576102a051610280511461579c576133a9610360615639565b6103605161034052336102a051146133ef576102a05161012052336101405261034051610160526133db6103606142ac565b610360511561579c5733610280511461579c575b602060e061028060405e613404610360615712565b610360f35b6004358060a01c61579c57610280526134236102c0615639565b6102c0516102a0526102a051613442575f6102c05260206102c06134f1565b61028051613459575f6102c05260206102c06134f1565b336040526102a05160605261346f6102c061418d565b6102c051613486575f6102e05260206102e06134f1565b3360405260016060526001608052600160a0526102a05160c0526134ab6102c0615695565b6102c05061028051604052336060526001608052600160a052600160c052600160e0526102a051610100526134e16102c0615712565b6102c05060016102c05260206102c05bf35b5f6102405261350d565b6044358060a01c61579c57610240525b6004358060a01c61579c57610200526024358060a01c61579c576102205261024051610260526102405161354f57613546610280615639565b61028051610260525b602060406102006101205e610260516101605261356d6102806142ac565b610280f35b5f5ffd5b6020615b6d604039604051815260405163d81f84b76060526001608052602060606024607c845afa6135aa573d5f5f3e3d5ffd5b3d602081183d60201002188060600160801161579c576060518060a01c61579c5760a0525060a0905051602082015260405163d81f84b760c052600260e052602060c0602460dc845afa613600573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c576101005250610100905051604082015260405163d81f84b7610120526003610140526020610120602461013c845afa61365c573d5f5f3e3d5ffd5b3d602081183d602010021880610120016101401161579c57610120518060a01c61579c576101605250610160905051606082015260405163d81f84b76101805260046101a0526020610180602461019c845afa6136bb573d5f5f3e3d5ffd5b3d602081183d602010021880610180016101a01161579c57610180518060a01c61579c576101c052506101c0905051608082015260405163d81f84b76101e05260056102005260206101e060246101fc845afa61371a573d5f5f3e3d5ffd5b3d602081183d6020100218806101e0016102001161579c576101e0518060a01c61579c57610220525061022090505160a082015260405163d81f84b7610240526006610260526020610240602461025c845afa613779573d5f5f3e3d5ffd5b3d602081183d602010021880610240016102601161579c57610240518060a01c61579c57610280525061028090505160c082015260405163d81f84b76102a05260076102c05260206102a060246102bc845afa6137d8573d5f5f3e3d5ffd5b3d602081183d6020100218806102a0016102c01161579c576102a0518060a01c61579c576102e052506102e090505160e082015260405163d81f84b7610300526008610320526020610300602461031c845afa613837573d5f5f3e3d5ffd5b3d602081183d602010021880610300016103201161579c57610300518060a01c61579c57610340525061034090505161010082015260405163d81f84b7610360526009610380526020610360602461037c845afa613897573d5f5f3e3d5ffd5b3d602081183d602010021880610360016103801161579c57610360518060a01c61579c576103a052506103a090505161012082015260405163d81f84b76103c052600a6103e05260206103c060246103dc845afa6138f7573d5f5f3e3d5ffd5b3d602081183d6020100218806103c0016103e01161579c576103c0518060a01c61579c57610400525061040090505161014082015260405163d81f84b761042052600b610440526020610420602461043c845afa613957573d5f5f3e3d5ffd5b3d602081183d602010021880610420016104401161579c57610420518060a01c61579c57610460525061046090505161016082015260405163d81f84b761048052600c6104a0526020610480602461049c845afa6139b7573d5f5f3e3d5ffd5b3d602081183d602010021880610480016104a01161579c57610480518060a01c61579c576104c052506104c090505161018082015260405163d81f84b76104e052600d6105005260206104e060246104fc845afa613a17573d5f5f3e3d5ffd5b3d602081183d6020100218806104e0016105001161579c576104e0518060a01c61579c5761052052506105209050516101a082015260405163d81f84b761054052600e610560526020610540602461055c845afa613a77573d5f5f3e3d5ffd5b3d602081183d602010021880610540016105601161579c57610540518060a01c61579c5761058052506105809050516101c082015260405163d81f84b76105a052600f6105c05260206105a060246105bc845afa613ad7573d5f5f3e3d5ffd5b3d602081183d6020100218806105a0016105c01161579c576105a0518060a01c61579c576105e052506105e09050516101e082015260405163d81f84b7610600526010610620526020610600602461061c845afa613b37573d5f5f3e3d5ffd5b3d602081183d602010021880610600016106201161579c57610600518060a01c61579c57610640525061064090505161020082015260405163d81f84b7610660526011610680526020610660602461067c845afa613b97573d5f5f3e3d5ffd5b3d602081183d602010021880610660016106801161579c57610660518060a01c61579c576106a052506106a090505161022082015250565b6020615b6d823950565b6020615b6d5f395f5163d81f84b7608052600660a052602060806024609c845afa613c06573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a01161579c576080518060a01c61579c5760c0525060c0905051606052606051613c43575f815250613c99565b606051632ba0309360805260405160a052602060806024609c845afa613c6b573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a01161579c576080518060011c61579c5760c0525060c09050518152505b565b60405115613cad576060511515613caf565b5f5b1561579c576060516370a0823160a0523060c052602060a0602460bc845afa613cda573d5f5f3e3d5ffd5b60203d1061579c5760a09050516080526080511561579c5760605163a9059cbb60a05260405160c05260805160e052602060a0604460bc5f855af1613d21573d5f5f3e3d5ffd5b3d613d3857803b1561579c57600161010052613d5f565b3d602081183d60201002188060a00160c01161579c5760a0518060011c61579c5761010052505b6101009050511561579c576040516060517fc2bfa18928a62b432789c9dda1f6bb4c519799a6b51f4dc2f74374e8f34207cf60805160a052602060a0a3565b6106c05115613db5576102406106c0825e50613dcc565b613dc0610900613576565b61090061024081835e50505b565b60403660e037606051613de45760805115613de6565b5f5b613ed15760805115613e775760a05163d81f84b761012052608051610140526020610120602461013c845afa613e1e573d5f5f3e3d5ffd5b3d602081183d602010021880610120016101401161579c57610120518060a01c61579c57610160525061016090505160e05260e0511561579c576080516101005260605115613f805760605160e0511861579c57613f80565b60605115613f805760a05163c4d9ba6361012052606051610140526020610120602461013c845afa613eab573d5f5f3e3d5ffd5b60203d1061579c5761012090505161010052610100511561579c5760605160e052613f80565b60c051631403184861012052604051610140526020610120602461013c845afa613efd573d5f5f3e3d5ffd5b60203d1061579c5761012090505161010052610100511561579c5760a05163d81f84b76101205261010051610140526020610120602461013c845afa613f45573d5f5f3e3d5ffd5b3d602081183d602010021880610120016101401161579c57610120518060a01c61579c57610160525061016090505160e05260e0511561579c575b60e051815261010051602082015250565b6020615b6d606039606051639693413060805260405160a052602060806024609c845afa613fc1573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a01161579c576080518060011c61579c5760c0525060c090505115613ffa57600181525061418b565b60605163d81f84b760a052600860c052602060a0602460bc845afa614021573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060a01c61579c5760e0525060e0905051608052608051156140ad57608051634756122d60a05260405160c052602060a0602460bc845afa61407e573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060011c61579c5760e0525060e09050516140af565b5f5b156140be57600181525061418b565b60605163d81f84b760c052600660e052602060c0602460dc845afa6140e5573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c57610100525061010090505160a05260a051156141755760a051632ba0309360c05260405160e052602060c0602460dc845afa614144573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060011c61579c576101005250610100905051614177565b5f5b1561418657600181525061418b565b5f8152505b565b606051631cfe78ba60a052602060a0600460bc845afa6141af573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060a01c61579c5760e0525060e09050516080526080516141ec575f8152506142aa565b60805163d81f84b760c052600160e052602060c0602460dc845afa614213573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c57610100525061010090505160a05260a051614252575f8152506142aa565b60a0516342af624e60c05260405160e052602060c0602460dc845afa61427a573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060011c61579c5761010052506101009050518152505b565b61012051604052610160516060526142c561018061418d565b610180516142d6575f81525061439e565b6101205163d34ddc056101a05260206101a060046101bc845afa6142fc573d5f5f3e3d5ffd5b3d602081183d6020100218806101a0016101c01161579c576101a0518060a01c61579c576101e052506101e09050516101805261018051614340575f81525061439e565b6101405161018051638da5cb5b6101a05260206101a060046101bc845afa61436a573d5f5f3e3d5ffd5b3d602081183d6020100218806101a0016101c01161579c576101a0518060a01c61579c576101e052506101e0905051148152505b565b606051196143d1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff815250614400565b5f60805260405160605111156143f95760605160405180820382811161579c57905090506080525b6080518152505b565b5f608052604051606051111561442a5760605160405180820382811161579c57905090506080525b608051815250565b6103405163969ea76d6104a052610260516104c052610200516104e05261024051610500526101406104a060646104bc845afa614471573d5f5f3e3d5ffd5b3d61014081183d610140100218806104a0016105e01161579c57806104a0016105e01161579c576104a0518060011c61579c57610600526104c0518060011c61579c57610620526104e0518060011c61579c5761064052610500518060011c61579c576106605260806105206106805e6105a0518060011c61579c57610700526105c05161072052506106009050610140816103605e50610360511561579c57610380511561579c576103a0511561579c576103c0511561579c576102a05160405261453e6104c0613f91565b6104c0516104a0526102c05161456b576102a051610240511461456557610460511561456d565b5f61456d565b5f5b156145af576104a0516145a65761024051610120526102a05161014052610340516101605261459d6104c06142ac565b6104c0516145a9565b60015b1561579c575b6102a0516104c0526102e051156145c657306104c0525b61022051610200516370a08231610500526104c051610520526020610500602461051c845afa6145f8573d5f5f3e3d5ffd5b60203d1061579c57610500905051808281188284100218905090506104e0526104e0511561579c576104a05115614635576104e051815250614796565b6102805163e1210e4f61058052610240516105a052610200516105c0526080610580604461059c845afa61466b573d5f5f3e3d5ffd5b3d608081183d608010021880610580016106001161579c5780610580016106001161579c57610580518060011c61579c576106205260606105a06106405e5061062090506080816105005e50610300516146d2576104405161032051101561579c576146e9565b610500516146e9576104205161052051101561579c575b610540516040526103e0516060526147026105a06143a0565b6105a05161058052610580511561579c576104e05161058051808281188284100218905090506104e05261056051604052610400516060526147456105c0614402565b6105c0516105a0526105a0511561579c576104e0516105a051808281188284100218905090506104e052610480516104e0516105405180820182811061579c57905090501061579c576104e0518152505b565b5f6103c0526102205163c9e4059c6103e05260206103e060046103fc845afa6147c3573d5f5f3e3d5ffd5b3d602081183d6020100218806103e0016104001161579c576103e0518060011c61579c576104205250610420905051156148295761012051614805575f614824565b610140516040526102205160605261481e61044061418d565b61044051155b6103c0525b6102005163222a390e6103e05261014051610400526103c05161042052803b1561579c575f6103e060446103fc5f855af1614866573d5f5f3e3d5ffd5b506102605163d81f84b7610400526002610420526020610400602461041c845afa614893573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060a01c61579c5761044052506104409050516103e0526103e05115614925576103e051637cdb0a4d610400526020610400600461041c5f855af16148f6573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060011c61579c57610440525061044050505b6101605115614a1257610120516149a3576103205163f355711d6104005261014051610420526102406101806104405e602061040061026461041c5f855af1614970573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060011c61579c5761068052506106805050614a12565b6103205163f355711d6104005261014051610420526102406101806104405e602061040061026461041c5f855af16149dd573d5f5f3e3d5ffd5b3d602081183d602010021880610400016104201161579c57610400518060011c61579c5761068052506106809050511561579c575b565b604036610ac037610740516040526107a0516060526107c0516080526109805160a0526109205160c052614a49610b00613dce565b610b00604081610b405e506040610b40610ac05e6109005163245a644c610b405261078051610b6052610ae051610b80526040610b406044610b5c845afa614a93573d5f5f3e3d5ffd5b3d604081183d604010021880610b4001610b801161579c5780610b4001610b801161579c57610b40518060011c61579c57610ba052610b6051610bc05250610ba09050604081610b005e5060606107406102005e610ae05161026052610ac051610280526107e0516102a05260406108206102c05e6040610b006103005e6109205161034052614b24610b60614432565b610b6051610b405261084051614bc457610740516323b872dd610b60526107e051610b8052610ac051610ba052610b4051610bc0526020610b606064610b7c5f855af1614b73573d5f5f3e3d5ffd5b3d614b8a57803b1561579c576001610be052614bb4565b3d602081183d602010021880610b6001610b801161579c57610b60518060011c61579c57610be052505b610be09050511561579c57614c48565b6107405163a9059cbb610b6052610ac051610b8052610b4051610ba0526020610b606044610b7c5f855af1614bfb573d5f5f3e3d5ffd5b3d614c1257803b1561579c576001610bc052614c3c565b3d602081183d602010021880610b6001610b801161579c57610b60518060011c61579c57610bc052505b610bc09050511561579c575b6108005115614cba57610ac0516385242616610b605261078051610b805261074051610ba052610b4051610bc05261080051610be052610240610880610c005e6020610b606102c4610b7c5f855af1614ca3573d5f5f3e3d5ffd5b60203d1061579c57610b60905051610b4052614d17565b610ac05163bfc78712610b605261078051610b805261074051610ba052610b4051610bc052610240610880610be05e6020610b606102a4610b7c5f855af1614d04573d5f5f3e3d5ffd5b60203d1061579c57610b60905051610b40525b610b0051614d5e576109005163c5bda89c610b605261078051610b8052610ae051610ba052803b1561579c575f610b606044610b7c5f855af1614d5c573d5f5f3e3d5ffd5b505b610a805163856ea3c6610b605261078051610b8052610ae051610ba052610ac051610bc05261074051610be052610240610880610c005e803b1561579c575f610b606102c4610b7c5f855af1614db6573d5f5f3e3d5ffd5b506108605115614de5575f6101205261078051610140526001610160526102406108806101805e614de5614798565b61096051635ad6a4b7610b605261074051610b80526020610b606024610b7c5f855af1614e14573d5f5f3e3d5ffd5b3d602081183d602010021880610b6001610b801161579c57610b60518060011c61579c57610ba05250610ba05050610740516107e051610780517ffea6f3dacc57406b0007933d492eb1d67328e5d55c8ede1fc213c6d63edca049610b4051610b6052610ac051610b8052610ae051610ba0526060610b60a4610b4051815250565b610220511561579c576102c0511561579c576102e0511561579c57610300511561579c576102a0516102405114614ed1576103205115614ed3565b5f5b15614f055761024051610120526102a051610140526104005161016052614efb6105a06142ac565b6105a0511561579c575b61050051634bd97a166105c052610240516105e0526102805161060052610200516106205261026051610640526102406103606106605e60206105c06102c46105dc845afa614f56573d5f5f3e3d5ffd5b60203d1061579c576105c09050516105a0526105a0511561579c57610220516105a05180828118828410021890509050815250565b604036610ba0376108a0516040526109005160605261092051608052610a605160a052610a005160c052614fc0610be0613dce565b610be0604081610c205e506040610c20610ba05e610a00516337f1a2b3610c80526108a051610ca0526108e051610cc05261094051610ce05260a0610c806064610c9c845afa615012573d5f5f3e3d5ffd5b3d60a081183d60a010021880610c8001610d201161579c5780610c8001610d201161579c57610c80518060011c61579c57610d4052610ca0518060011c61579c57610d6052610cc0518060011c61579c57610d8052610ce0518060011c61579c57610da052610d0051610dc05250610d40905060a081610be05e5060606108a06102005e6040610ba06102605e610940516102a05260a0610be06102c05e6102406109606103605e6150c5610ca0614e96565b610ca051610c80525f610ca052610ba05163402495a4610cc0526108e051610ce0526108a051610d0052610c8051610d20526108e051610d4052610240610960610d605e6040610cc06102c4610cdc5f855af1615124573d5f5f3e3d5ffd5b3d604081183d604010021880610cc001610d001161579c57610cc051610fa052610ce0518060011c61579c57610fc05250610fa09050604081610fe05e506040610fe0610c805e610ca0516151c957610ba0516396c3a427610ce0526108e051610d00526108a051610d20526020610ce06044610cfc845afa6151a9573d5f5f3e3d5ffd5b60203d1061579c57610ce0905051610cc052610c6051610cc0511061579c575b610b605163856ea3c6610cc0526108e051610ce052610bc051610d0052610ba051610d20526108a051610d4052610240610960610d605e803b1561579c575f610cc06102c4610cdc5f855af1615221573d5f5f3e3d5ffd5b50610a4051635ad6a4b7610cc0526108a051610ce0526020610cc06024610cdc5f855af1615251573d5f5f3e3d5ffd5b3d602081183d602010021880610cc001610ce01161579c57610cc0518060011c61579c57610d005250610d005050610940516108a0516108e0517f6b0d92ac92e3ebfdb54eaa7f092d7be054f8939df0c41f1c961f80fdb5d1e422610c8051610cc052610ba051610ce052610bc051610d0052610ca051610d20526080610cc0a4610c8051815250565b60a05160e052604051156152f05760c05160e0525b60605160e0516370a082316101205233610140526020610120602461013c845afa61531d573d5f5f3e3d5ffd5b60203d1061579c576101209050518082811882841002189050905061010052610100511561579c576080511561579c576040516153df5760a0516323b872dd6101205233610140526080516101605261010051610180526020610120606461013c5f855af161538e573d5f5f3e3d5ffd5b3d6153a557803b1561579c5760016101a0526153cf565b3d602081183d602010021880610120016101401161579c57610120518060011c61579c576101a052505b6101a09050511561579c576154b0565b60c0516323b872dd610120523361014052306101605261010051610180526020610120606461013c5f855af1615417573d5f5f3e3d5ffd5b3d61542e57803b1561579c5760016101a052615458565b3d602081183d602010021880610120016101401161579c57610120518060011c61579c576101a052505b6101a09050511561579c5760c05163ba0876526101205261010051610140526080516101605230610180526020610120606461013c5f855af161549d573d5f5f3e3d5ffd5b60203d1061579c57610120905051610100525b61010051815250565b606051631cfe78ba60a052602060a0600460bc845afa6154db573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060a01c61579c5760e0525060e0905051608052608051615518575f815250615637565b608051639693413060a05260405160c052602060a0602460bc845afa615540573d5f5f3e3d5ffd5b3d602081183d60201002188060a00160c01161579c5760a0518060011c61579c5760e0525060e090505115615579576001815250615637565b60805163d81f84b760c052600360e052602060c0602460dc845afa6155a0573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060a01c61579c57610100525061010090505160a05260a0516155df575f815250615637565b60a051639693413060c05260405160e052602060c0602460dc845afa615607573d5f5f3e3d5ffd5b3d602081183d60201002188060c00160e01161579c5760c0518060011c61579c5761010052506101009050518152505b565b6020615b6d5f395f5163d81f84b76040526005606052602060406024605c845afa615666573d5f5f3e3d5ffd5b3d602081183d60201002188060400160601161579c576040518060a01c61579c57608052506080905051815250565b6060606060e05e60c051636e6f30296101405260405161016052606060e06101805e803b1561579c575f610140608461015c5f855af16156d7573d5f5f3e3d5ffd5b50336040517fa1df7ba437478e42ba351e23d5875bc241b38d2f42357ce394db3831110d9fc7606060606101405e6060610140a36001815250565b608060806101205e6101005163fac3ef616101a0526060516101c0526040516101e05260806101206102005e803b1561579c575f6101a060c46101bc5f855af161575e573d5f5f3e3d5ffd5b50336040516060517fe57f0d8a88a7e27cf4de7394d7913a3c69cdc3a26b5d956d55c8abe3d9f04271608060806101a05e60806101a0a46001815250565b5f80fd000a5ac50500b259b50605df5a5508000f5aed0600085b1d031cce587d0e001759250500a75a250600065b5d02000d58ed07014459e50800b75a950601d457f50800195b350500a5594d0707825835090035598506a5c7434a00640005b8b419741306002587a5b71618030045dfcd412e07180085b187bd260210000536b20ad41e070065205f940930ee00252fe0f37f0b8d0065246f9d992a97006509b9f55600770005225b962e105000659d361ff93409002524ae6a27010800458785beba292c0045d4c21c8e182100655501f1c6074700a540fd6f940087000569328dec06f6006534146458326d00653b6fccc0009500057dd5da70251f0085b30420f9155d0065d1c469162d28002553992db72b9a00452ef838b632410045f45346dc02690065843fdaee1e5100a551cff8d906a80025371fd8e60b4b0025f813ce6e0dbc00e5dd74b3102aa1008502329a2900a30025f412e5e818bf00c564505a3e22cb00c5bdc62a7c13110045b206b9c932a20085958c288b31430065a321c62804db02e53fb7de5202ba00a594863d361b060025e64fe31f1e7100c57053a18f01500045556bfd9c0d0200658d5c9efc13e70025cf29e4c9321f00253969c94c24c500452f2800831e3b00853dcbe8600d5c00a5f340fa01021b0025758289482eaf00254567d2d41655010547e7ef240251004581c63a8d15b700a54edab157081000459ab7eb6b226e0085be6979e520090085b1e168382ef90065f0ae528629210025f74ade6830d2000571b78d170dfa0105c5ebeaec09b00025c6f1649f028b00858dc17754317b00852cf0fd552f0b008556cc9045188100a5cfca23190d8700c55481c8c017c70025025699f503620045f29c9f631ff00065acb708150b670045db33279d34fd0065815a439228480045db89bf5904ce00a5c9a6eea7281e000591774d06159900858b8a23890d3e0085b7097b4e282e0025263fe583230a00e56bc67a221fe10045402d88830b110005c7c77bb22ee30045f3fef3a306de0045ce6442592ba40065e68d3569097600054b3fd14809cc0045897b357b0bbd008557d094c5184c00858b655a370a2100853ea63e8134f30045ea5bda9413f20045918c344709f20065c721198632e000a52cc7d2e3254700a506dfaff2257c00c574ff30f410320045eba2073a10b000a561484d1d311400454a9186b10ff600255fd76b71332700c5c0ac867515e200c579942b961ad700050128d538107b00854fa3d65c161700e59401e3ac1b3f00451768d1cc250100656a0ac6c0229600a59cb2b0622d32004560f23e3725bb00e5c5f7de4e10ee00c5a9d12127221400452febc58d225000650000000000000000000000006162df1b329e157479f8f1407e888260e0ec3d2b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

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

0000000000000000000000006162df1b329e157479f8f1407e888260e0ec3d2b0000000000000000000000000000000000000000000000000000000000000001

-----Decoded View---------------
Arg [0] : _ripeHq (address): 0x6162df1b329E157479F8f1407E888260E0EC3d2b
Arg [1] : _shouldPause (bool): True

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000006162df1b329e157479f8f1407e888260e0ec3d2b
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.