Source Code
Latest 25 from a total of 1,303 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Create_loan | 24601988 | 2 hrs ago | IN | 0 ETH | 0.00037999 | ||||
| Create_loan | 24601984 | 2 hrs ago | IN | 0 ETH | 0.00038897 | ||||
| Create_loan | 24601982 | 2 hrs ago | IN | 0 ETH | 0.00038895 | ||||
| Create_loan | 24601980 | 2 hrs ago | IN | 0 ETH | 0.00049415 | ||||
| Settle_loan | 24585562 | 2 days ago | IN | 0 ETH | 0.00035078 | ||||
| Replace_loan | 24573113 | 4 days ago | IN | 0 ETH | 0.00029909 | ||||
| Replace_loan | 24573111 | 4 days ago | IN | 0 ETH | 0.00029888 | ||||
| Replace_loan | 24573108 | 4 days ago | IN | 0 ETH | 0.00029922 | ||||
| Settle_loan | 24573102 | 4 days ago | IN | 0 ETH | 0.00031659 | ||||
| Replace_loan | 24565981 | 5 days ago | IN | 0 ETH | 0.00041521 | ||||
| Create_loan | 24562148 | 5 days ago | IN | 0 ETH | 0.00045743 | ||||
| Settle_loan | 24561246 | 5 days ago | IN | 0 ETH | 0.00033481 | ||||
| Settle_loan | 24561212 | 5 days ago | IN | 0 ETH | 0.00026081 | ||||
| Settle_loan | 24545997 | 7 days ago | IN | 0 ETH | 0.00030537 | ||||
| Settle_loan | 24535761 | 9 days ago | IN | 0 ETH | 0.00033038 | ||||
| Replace_loan | 24535305 | 9 days ago | IN | 0 ETH | 0.00015484 | ||||
| Create_loan | 24532549 | 9 days ago | IN | 0 ETH | 0.0004036 | ||||
| Create_loan | 24528815 | 10 days ago | IN | 0 ETH | 0.00046429 | ||||
| Create_loan | 24528397 | 10 days ago | IN | 0 ETH | 0.00040047 | ||||
| Replace_loan | 24522609 | 11 days ago | IN | 0 ETH | 0.00001342 | ||||
| Claim_defaulted_... | 24520625 | 11 days ago | IN | 0 ETH | 0.00022561 | ||||
| Settle_loan | 24508600 | 13 days ago | IN | 0 ETH | 0.00026384 | ||||
| Settle_loan | 24508597 | 13 days ago | IN | 0 ETH | 0.00027339 | ||||
| Settle_loan | 24508594 | 13 days ago | IN | 0 ETH | 0.00027322 | ||||
| Settle_loan | 24508590 | 13 days ago | IN | 0 ETH | 0.00027341 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
P2PLendingNfts
Compiler Version
vyper:0.3.10
Contract Source Code (Vyper language format)
# @version 0.3.10
"""
@title P2PLendingNfts
@author [Zharta](https://zharta.io/)
@notice This contract facilitates peer-to-peer lending using NFTs as collateral.
@dev It facilitates peer-to-peer lending using NFTs as collateral.
The contract allows lenders to offer loans and borrowers to accept them by providing NFTs as collateral.
Key functionalities include:
- Creating and managing loan offers
- Accepting loan offers and locking NFTs as collateral
- Accepts ERC721 and CryptoPunks NFTs as collateral
- Delegating the collateral using [Delegate](https://delegate.xyz/) DelegateRegistry v2
- Settling loans by repaying the principal and interest
- Claiming collateral in case of loan default
- Replacing existing loans with new terms
- Four types of fees are supported: protocol fee, origination fee, lender broker fee, and borrower broker fee
- Managing protocol fees and authorized proxies
- Handling ownership transfer of the contract
- Loan state is kept hashed in the contract to save gas
The contract ensures secure and transparent lending operations within the Zharta ecosystem.
"""
# Interfaces
from vyper.interfaces import ERC165 as IERC165
from vyper.interfaces import ERC721 as IERC721
from vyper.interfaces import ERC20 as IERC20
interface CryptoPunksMarket:
def transferPunk(to: address, punkIndex: uint256): nonpayable
def buyPunk(punkIndex: uint256): payable
def punksOfferedForSale(punkIndex: uint256) -> PunkOffer: view
def punkIndexToAddress(punkIndex: uint256) -> address: view
def offerPunkForSaleToAddress(punkIndex: uint256, minSalePriceInWei: uint256, toAddress: address): nonpayable
interface DelegationRegistry:
def delegateERC721(delegate: address, contract: address, token_id: uint256, rights: bytes32, _value: bool) -> bytes32: nonpayable
interface P2PLendingControl:
def get_collection_status(collection_key_hash: bytes32) -> CollectionStatus: nonpayable
# Structs
PROOF_MAX_SIZE: constant(uint256) = 32
MAX_FEES: constant(uint256) = 4
BPS: constant(uint256) = 10000
enum FeeType:
PROTOCOL_FEE
ORIGINATION_FEE
LENDER_BROKER_FEE
BORROWER_BROKER_FEE
enum OfferType:
TOKEN
COLLECTION
TRAIT
struct Fee:
type: FeeType
upfront_amount: uint256
interest_bps: uint256
wallet: address
struct FeeAmount:
type: FeeType
amount: uint256
wallet: address
struct Offer:
principal: uint256
interest: uint256
payment_token: address
duration: uint256
origination_fee_amount: uint256
broker_upfront_fee_amount: uint256
broker_settlement_fee_bps: uint256
broker_address: address
offer_type: OfferType
token_id: uint256
token_range_min: uint256
token_range_max: uint256
collection_key_hash: bytes32
trait_hash: bytes32
expiration: uint256
lender: address
pro_rata: bool
size: uint256
tracing_id: bytes32
struct Signature:
v: uint256
r: uint256
s: uint256
struct SignedOffer:
offer: Offer
signature: Signature
struct Loan:
id: bytes32
offer_id: bytes32
offer_tracing_id: bytes32
amount: uint256 # principal - origination_fee_amount
interest: uint256
payment_token: address
maturity: uint256
start_time: uint256
borrower: address
lender: address
collateral_contract: address
collateral_token_id: uint256
fees: DynArray[Fee, MAX_FEES]
pro_rata: bool
delegate: address
struct CollectionStatus:
contract: address
trait_root: bytes32
struct PunkOffer:
isForSale: bool
punkIndex: uint256
seller: address
minValue: uint256
onlySellTo: address
event LoanCreated:
id: bytes32
amount: uint256
interest: uint256
payment_token: address
maturity: uint256
start_time: uint256
borrower: address
lender: address
collateral_contract: address
collateral_token_id: uint256
fees: DynArray[Fee, MAX_FEES]
pro_rata: bool
offer_id: bytes32
offer_tracing_id: bytes32
delegate: address
event LoanReplaced:
id: bytes32
amount: uint256
interest: uint256
payment_token: address
maturity: uint256
start_time: uint256
collateral_contract: address
collateral_token_id: uint256
borrower: address
lender: address
fees: DynArray[Fee, MAX_FEES]
pro_rata: bool
original_loan_id: bytes32
paid_principal: uint256
paid_interest: uint256
paid_settlement_fees: DynArray[FeeAmount, MAX_FEES]
offer_id: bytes32
offer_tracing_id: bytes32
event LoanReplacedByLender:
id: bytes32
amount: uint256
interest: uint256
payment_token: address
maturity: uint256
start_time: uint256
collateral_contract: address
collateral_token_id: uint256
borrower: address
lender: address
fees: DynArray[Fee, MAX_FEES]
pro_rata: bool
original_loan_id: bytes32
paid_principal: uint256
paid_interest: uint256
paid_settlement_fees: DynArray[FeeAmount, MAX_FEES]
borrower_compensation: uint256
offer_id: bytes32
offer_tracing_id: bytes32
event LoanPaid:
id: bytes32
borrower: address
lender: address
payment_token: address
paid_principal: uint256
paid_interest: uint256
paid_settlement_fees: DynArray[FeeAmount, MAX_FEES]
event LoanCollateralClaimed:
id: bytes32
borrower: address
lender: address
collateral_contract: address
collateral_token_id: uint256
event OfferRevoked:
offer_id: bytes32
lender: address
collection_key_hash: bytes32
offer_type: OfferType
event OwnerProposed:
owner: address
proposed_owner: address
event OwnershipTransferred:
old_owner: address
new_owner: address
event ProtocolFeeSet:
old_upfront_fee: uint256
old_settlement_fee: uint256
new_upfront_fee: uint256
new_settlement_fee: uint256
event ProtocolWalletChanged:
old_wallet: address
new_wallet: address
event ProxyAuthorizationChanged:
proxy: address
value: bool
event TransferFailed:
_to: address
amount: uint256
event PendingTransfersClaimed:
_to: address
amount: uint256
# Global variables
owner: public(address)
proposed_owner: public(address)
payment_token: public(immutable(address))
loans: public(HashMap[bytes32, bytes32])
delegation_registry: public(immutable(DelegationRegistry))
cryptopunks: public(immutable(CryptoPunksMarket))
p2p_control: public(immutable(P2PLendingControl))
protocol_wallet: public(address)
protocol_upfront_fee: public(uint256)
protocol_settlement_fee: public(uint256)
max_protocol_upfront_fee: public(immutable(uint256))
max_protocol_settlement_fee: public(immutable(uint256))
max_lender_broker_settlement_fee: public(immutable(uint256))
max_borrower_broker_settlement_fee: public(immutable(uint256))
offer_count: public(HashMap[bytes32, uint256])
revoked_offers: public(HashMap[bytes32, bool])
authorized_proxies: public(HashMap[address, bool])
pending_transfers: public(HashMap[address, uint256])
VERSION: public(constant(String[30])) = "P2PLendingNfts.20241002"
ZHARTA_DOMAIN_NAME: constant(String[6]) = "Zharta"
ZHARTA_DOMAIN_VERSION: constant(String[1]) = "1"
DOMAIN_TYPE_HASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
OFFER_TYPE_DEF: constant(String[413]) = "Offer(uint256 principal,uint256 interest,address payment_token,uint256 duration,uint256 origination_fee_amount," \
"uint256 broker_upfront_fee_amount,uint256 broker_settlement_fee_bps,address broker_address," \
"uint256 offer_type,uint256 token_id,uint256 token_range_min,uint256 token_range_max,bytes32 collection_key_hash," \
"bytes32 trait_hash,uint256 expiration,address lender,bool pro_rata,uint256 size,bytes32 tracing_id)"
OFFER_TYPE_HASH: constant(bytes32) = keccak256(OFFER_TYPE_DEF)
offer_sig_domain_separator: immutable(bytes32)
@external
def __init__(
_payment_token: address,
_p2p_control: address,
_delegation_registry: address,
_cryptopunks: address,
_protocol_upfront_fee: uint256,
_protocol_settlement_fee: uint256,
_protocol_wallet: address,
_max_protocol_upfront_fee: uint256,
_max_protocol_settlement_fee: uint256,
_max_lender_broker_settlement_fee: uint256,
_max_borrower_broker_settlement_fee: uint256,
):
"""
@notice Initialize the contract with the given parameters.
@param _payment_token The address of the payment token.
@param _delegation_registry The address of the delegation registry.
@param _cryptopunks The address of the CryptoPunksMarket contract.
@param _protocol_upfront_fee The percentage (bps) of the principal paid to the protocol at origination.
@param _protocol_settlement_fee The percentage (bps) of the interest paid to the protocol at settlement.
@param _protocol_wallet The address where the protocol fees are accrued.
"""
assert _protocol_wallet != empty(address), "wallet is the zero address"
assert _payment_token != empty(address), "payment token is zero"
assert _p2p_control != empty(address), "p2p control is zero"
assert _delegation_registry != empty(address), "delegation registry is zero"
assert _protocol_upfront_fee <= _max_protocol_upfront_fee, "upfront fee exceeds max"
assert _protocol_settlement_fee <= _max_protocol_settlement_fee, "settlement fee exceeds max"
self.owner = msg.sender
payment_token = _payment_token
p2p_control = P2PLendingControl(_p2p_control)
delegation_registry = DelegationRegistry(_delegation_registry)
cryptopunks = CryptoPunksMarket(_cryptopunks)
max_protocol_upfront_fee = _max_protocol_upfront_fee
max_protocol_settlement_fee = _max_protocol_settlement_fee
max_lender_broker_settlement_fee = _max_lender_broker_settlement_fee
max_borrower_broker_settlement_fee = _max_borrower_broker_settlement_fee
self.protocol_upfront_fee = _protocol_upfront_fee
self.protocol_settlement_fee = _protocol_settlement_fee
self.protocol_wallet = _protocol_wallet
offer_sig_domain_separator = keccak256(
_abi_encode(
DOMAIN_TYPE_HASH,
keccak256(ZHARTA_DOMAIN_NAME),
keccak256(ZHARTA_DOMAIN_VERSION),
chain.id,
self
)
)
# Config functions
@external
def set_protocol_fee(protocol_upfront_fee: uint256, protocol_settlement_fee: uint256):
"""
@notice Set the protocol fee
@dev Sets the protocol fee to the given value and logs the event. Admin function.
@param protocol_upfront_fee The new protocol upfront fee.
@param protocol_settlement_fee The new protocol settlement fee.
"""
assert msg.sender == self.owner, "not owner"
assert protocol_upfront_fee <= max_protocol_upfront_fee, "upfront fee exceeds max"
assert protocol_settlement_fee <= max_protocol_settlement_fee, "settlement fee exceeds max"
log ProtocolFeeSet(self.protocol_upfront_fee, self.protocol_settlement_fee, protocol_upfront_fee, protocol_settlement_fee)
self.protocol_upfront_fee = protocol_upfront_fee
self.protocol_settlement_fee = protocol_settlement_fee
@external
def change_protocol_wallet(new_protocol_wallet: address):
"""
@notice Change the protocol wallet
@dev Changes the protocol wallet to the given address and logs the event. Admin function.
@param new_protocol_wallet The new protocol wallet.
"""
assert msg.sender == self.owner, "not owner"
assert new_protocol_wallet != empty(address), "wallet is the zero address"
log ProtocolWalletChanged(self.protocol_wallet, new_protocol_wallet)
self.protocol_wallet = new_protocol_wallet
@external
def set_proxy_authorization(_proxy: address, _value: bool):
"""
@notice Set authorization
@dev Sets the authorization for the given proxy and logs the event. Admin function.
@param _proxy The address of the proxy.
@param _value The value of the authorization.
"""
assert msg.sender == self.owner, "not owner"
self.authorized_proxies[_proxy] = _value
log ProxyAuthorizationChanged(_proxy, _value)
@external
def propose_owner(_address: address):
"""
@notice Propose a new owner
@dev Proposes a new owner and logs the event. Admin function.
@param _address The address of the proposed owner.
"""
assert msg.sender == self.owner, "not owner"
assert _address != empty(address), "_address is zero"
log OwnerProposed(self.owner, _address)
self.proposed_owner = _address
@external
def claim_ownership():
"""
@notice Claim the ownership of the contract
@dev Claims the ownership of the contract and logs the event. Requires the caller to be the proposed owner.
"""
assert msg.sender == self.proposed_owner, "not the proposed owner"
log OwnershipTransferred(self.owner, self.proposed_owner)
self.owner = msg.sender
self.proposed_owner = empty(address)
# Core functions
@external
def create_loan(
offer: SignedOffer,
collateral_token_id: uint256,
collateral_proof: DynArray[bytes32, PROOF_MAX_SIZE],
delegate: address,
borrower_broker_upfront_fee_amount: uint256,
borrower_broker_settlement_fee_bps: uint256,
borrower_broker: address
) -> bytes32:
"""
@notice Create a loan.
@param offer The signed offer.
@param collateral_token_id The ID of the collateral token.
@param delegate The address of the delegate. If empty, no delegation is set.
@param borrower_broker_upfront_fee_amount The upfront fee amount for the borrower broker.
@param borrower_broker_settlement_fee_bps The settlement fee basis points relative to the interest for the borrower broker.
@param borrower_broker The address of the borrower broker.
@return The ID of the created loan.
"""
assert self._is_offer_signed_by_lender(offer, offer.offer.lender), "offer not signed by lender"
assert offer.offer.expiration > block.timestamp, "offer expired"
assert offer.offer.payment_token == payment_token, "invalid payment token"
assert offer.offer.origination_fee_amount <= offer.offer.principal, "origination fee gt principal"
collection_status: CollectionStatus = p2p_control.get_collection_status(offer.offer.collection_key_hash)
self._validate_token_ids(offer.offer, collateral_token_id, collection_status, collateral_proof)
fees: DynArray[Fee, MAX_FEES] = self._get_loan_fees(offer.offer, borrower_broker_upfront_fee_amount, borrower_broker_settlement_fee_bps, borrower_broker)
total_upfront_fees: uint256 = 0
for fee in fees:
total_upfront_fees += fee.upfront_amount
offer_id: bytes32 = self._compute_signed_offer_id(offer)
loan: Loan = Loan({
id: empty(bytes32),
offer_id: offer_id,
offer_tracing_id: offer.offer.tracing_id,
amount: offer.offer.principal,
interest: offer.offer.interest,
payment_token: offer.offer.payment_token,
maturity: block.timestamp + offer.offer.duration,
start_time: block.timestamp,
borrower: msg.sender if not self.authorized_proxies[msg.sender] else tx.origin,
lender: offer.offer.lender,
collateral_contract: collection_status.contract,
collateral_token_id: collateral_token_id,
fees: fees,
pro_rata: offer.offer.pro_rata,
delegate: delegate
})
loan.id = self._compute_loan_id(loan)
assert self.loans[loan.id] == empty(bytes32), "loan already exists"
self._check_and_update_offer_state(offer)
self.loans[loan.id] = self._loan_state_hash(loan)
self._store_collateral(loan.borrower, loan.collateral_contract, loan.collateral_token_id)
self._transfer_funds(loan.lender, loan.borrower, loan.amount - total_upfront_fees + offer.offer.broker_upfront_fee_amount)
for fee in fees:
if fee.type != FeeType.ORIGINATION_FEE and fee.upfront_amount > 0:
self._transfer_funds(loan.lender, fee.wallet, fee.upfront_amount)
if delegate != empty(address):
self._set_delegation(delegate, loan.collateral_contract, loan.collateral_token_id, True)
log LoanCreated(
loan.id,
loan.amount,
loan.interest,
loan.payment_token,
loan.maturity,
loan.start_time,
loan.borrower,
loan.lender,
loan.collateral_contract,
loan.collateral_token_id,
loan.fees,
loan.pro_rata,
offer_id,
offer.offer.tracing_id,
delegate
)
return loan.id
@external
def settle_loan(loan: Loan):
"""
@notice Settle a loan.
@param loan The loan to be settled.
"""
assert self._is_loan_valid(loan), "invalid loan"
assert block.timestamp <= loan.maturity, "loan defaulted"
assert self._check_user(loan.borrower), "not borrower"
interest: uint256 = self._compute_settlement_interest(loan)
settlement_fees_total: uint256 = 0
settlement_fees: DynArray[FeeAmount, MAX_FEES] = []
borrower_broker_fee_amount: uint256 = 0
settlement_fees, settlement_fees_total, borrower_broker_fee_amount = self._get_settlement_fees(loan, interest)
self.loans[loan.id] = empty(bytes32)
self._reduce_offer_count(loan.offer_tracing_id)
self._receive_funds(loan.borrower, loan.amount + interest + borrower_broker_fee_amount)
self._send_funds(loan.lender, loan.amount + interest - settlement_fees_total + borrower_broker_fee_amount)
for fee in settlement_fees:
self._send_funds(fee.wallet, fee.amount)
self._transfer_collateral(loan.borrower, loan.collateral_contract, loan.collateral_token_id)
if loan.delegate != empty(address):
self._set_delegation(loan.delegate, loan.collateral_contract, loan.collateral_token_id, False)
log LoanPaid(
loan.id,
loan.borrower,
loan.lender,
loan.payment_token,
loan.amount,
interest,
settlement_fees
)
@external
def claim_defaulted_loan_collateral(loan: Loan):
"""
@notice Claim defaulted loan collateral.
@param loan The loan whose collateral is to be claimed. The loan maturity must have been passed.
"""
assert self._is_loan_valid(loan), "invalid loan"
assert block.timestamp > loan.maturity, "loan not defaulted"
assert self._check_user(loan.lender), "not lender"
self.loans[loan.id] = empty(bytes32)
self._transfer_collateral(loan.lender, loan.collateral_contract, loan.collateral_token_id)
if loan.delegate != empty(address):
self._set_delegation(loan.delegate, loan.collateral_contract, loan.collateral_token_id, False)
log LoanCollateralClaimed(
loan.id,
loan.borrower,
loan.lender,
loan.collateral_contract,
loan.collateral_token_id
)
@external
def replace_loan(
loan: Loan,
offer: SignedOffer,
collateral_proof: DynArray[bytes32, PROOF_MAX_SIZE],
borrower_broker_upfront_fee_amount: uint256,
borrower_broker_settlement_fee_bps: uint256,
borrower_broker: address
) -> bytes32:
"""
@notice Replace an existing loan by accepting a new offer over the same collateral. The current loan is settled and the new loan is created. Must be called by the borrower.
@dev No collateral transfer is required and the delegation is not changed. The borrower must be the same as the borrower of the current loan.
@param loan The loan to be replaced.
@param offer The new signed offer.
@param borrower_broker_upfront_fee_amount The upfront fee amount for the borrower broker.
@param borrower_broker_settlement_fee_bps The settlement fee basis points relative to the interest for the borrower broker.
@param borrower_broker The address of the borrower broker, if any.
@return The ID of the new loan.
"""
assert self._is_loan_valid(loan), "invalid loan"
assert self._check_user(loan.borrower), "not borrower"
assert block.timestamp <= loan.maturity, "loan defaulted"
assert self._is_offer_signed_by_lender(offer, offer.offer.lender), "offer not signed by lender"
assert offer.offer.expiration > block.timestamp, "offer expired"
assert offer.offer.payment_token == payment_token, "invalid payment token"
assert offer.offer.origination_fee_amount <= offer.offer.principal, "origination fee gt principal"
collection_status: CollectionStatus = p2p_control.get_collection_status(offer.offer.collection_key_hash)
self._validate_token_ids(offer.offer, loan.collateral_token_id, collection_status, collateral_proof)
assert collection_status.contract == loan.collateral_contract, "collateral contract mismatch"
self._check_and_update_offer_state(offer)
self._reduce_offer_count(loan.offer_tracing_id)
principal_delta: int256 = convert(offer.offer.principal, int256) - convert(loan.amount, int256)
interest: uint256 = self._compute_settlement_interest(loan)
settlement_fees_total: uint256 = 0
settlement_fees: DynArray[FeeAmount, MAX_FEES] = []
borrower_broker_fee_amount: uint256 = 0
settlement_fees, settlement_fees_total, borrower_broker_fee_amount = self._get_settlement_fees(loan, interest)
new_loan_fees: DynArray[Fee, MAX_FEES] = self._get_loan_fees(offer.offer, borrower_broker_upfront_fee_amount, borrower_broker_settlement_fee_bps, borrower_broker)
total_upfront_fees: uint256 = 0
for fee in new_loan_fees:
total_upfront_fees += fee.upfront_amount
self.loans[loan.id] = empty(bytes32)
borrower_delta: int256 = principal_delta - convert(total_upfront_fees + interest + borrower_broker_fee_amount, int256) + convert(offer.offer.broker_upfront_fee_amount, int256)
current_lender_delta: uint256 = loan.amount + interest - settlement_fees_total + borrower_broker_fee_amount
new_lender_delta_abs: uint256 = offer.offer.principal - offer.offer.origination_fee_amount + offer.offer.broker_upfront_fee_amount
if borrower_delta < 0:
self._receive_funds(loan.borrower, convert(-1 * borrower_delta, uint256))
if loan.lender != offer.offer.lender:
self._receive_funds(offer.offer.lender, new_lender_delta_abs)
self._send_funds(loan.lender, current_lender_delta)
elif current_lender_delta > new_lender_delta_abs:
self._send_funds(loan.lender, current_lender_delta - new_lender_delta_abs)
elif current_lender_delta < new_lender_delta_abs:
self._receive_funds(loan.lender, new_lender_delta_abs - current_lender_delta)
if borrower_delta > 0:
self._send_funds(loan.borrower, convert(borrower_delta, uint256))
for fee in settlement_fees:
self._send_funds(fee.wallet, fee.amount)
for fee in new_loan_fees:
if fee.type != FeeType.ORIGINATION_FEE and fee.upfront_amount > 0:
self._send_funds(fee.wallet, fee.upfront_amount)
offer_id: bytes32 = self._compute_signed_offer_id(offer)
new_loan: Loan = Loan({
id: empty(bytes32),
offer_id: offer_id,
offer_tracing_id: offer.offer.tracing_id,
amount: offer.offer.principal,
interest: offer.offer.interest,
payment_token: offer.offer.payment_token,
maturity: block.timestamp + offer.offer.duration,
start_time: block.timestamp,
borrower: loan.borrower,
lender: offer.offer.lender,
collateral_contract: collection_status.contract,
collateral_token_id: loan.collateral_token_id,
fees: new_loan_fees,
pro_rata: offer.offer.pro_rata,
delegate: loan.delegate
})
new_loan.id = self._compute_loan_id(new_loan)
assert self.loans[new_loan.id] == empty(bytes32), "loan already exists"
self.loans[new_loan.id] = self._loan_state_hash(new_loan)
log LoanReplaced(
new_loan.id,
new_loan.amount,
new_loan.interest,
new_loan.payment_token,
new_loan.maturity,
new_loan.start_time,
new_loan.collateral_contract,
new_loan.collateral_token_id,
new_loan.borrower,
new_loan.lender,
new_loan.fees,
new_loan.pro_rata,
loan.id,
loan.amount,
interest,
settlement_fees,
offer_id,
offer.offer.tracing_id
)
return new_loan.id
@external
def replace_loan_lender(loan: Loan, offer: SignedOffer, collateral_proof: DynArray[bytes32, PROOF_MAX_SIZE]) -> bytes32:
"""
@notice Replace a loan by the lender. The current loan is settled and the new loan is created. Must be called by the lender.
@dev No collateral transfer is required and the delegation is not changed. The borrower must be the same as the borrower of the current loan. No funds are required from the borrower. Also no funds are required from the lender, except when the current and new lender are the same.
@param loan The loan to be replaced.
@param offer The new signed offer.
@return The ID of the new loan.
"""
assert self._is_loan_valid(loan), "invalid loan"
assert self._check_user(loan.lender), "not lender"
assert block.timestamp <= loan.maturity, "loan defaulted"
assert self._is_offer_signed_by_lender(offer, offer.offer.lender), "offer not signed by lender"
assert offer.offer.expiration > block.timestamp, "offer expired"
assert offer.offer.payment_token == payment_token, "invalid payment token"
assert offer.offer.origination_fee_amount <= offer.offer.principal, "origination fee gt principal"
assert block.timestamp + offer.offer.duration >= loan.maturity, "maturity before loan maturity"
collection_status: CollectionStatus = p2p_control.get_collection_status(offer.offer.collection_key_hash)
self._validate_token_ids(offer.offer, loan.collateral_token_id, collection_status, collateral_proof)
assert collection_status.contract == loan.collateral_contract, "collateral contract mismatch"
self._check_and_update_offer_state(offer)
self._reduce_offer_count(loan.offer_tracing_id)
principal_delta: int256 = convert(offer.offer.principal, int256) - convert(loan.amount, int256)
interest: uint256 = self._compute_settlement_interest(loan)
settlement_fees_total: uint256 = 0
settlement_fees: DynArray[FeeAmount, MAX_FEES] = []
borrower_broker_fee_amount: uint256 = 0
settlement_fees, settlement_fees_total, borrower_broker_fee_amount = self._get_settlement_fees(loan, interest)
new_loan_fees: DynArray[Fee, MAX_FEES] = self._get_loan_fees(offer.offer, 0, 0, empty(address))
total_upfront_fees: uint256 = 0
for fee in new_loan_fees:
total_upfront_fees += fee.upfront_amount
self.loans[loan.id] = empty(bytes32)
max_interest_delta: uint256 = self._compute_max_interest_delta(loan, offer.offer, interest, borrower_broker_fee_amount)
borrower_compensation: uint256 = convert(max(convert(max_interest_delta, int256), convert(interest + borrower_broker_fee_amount, int256) - principal_delta), uint256)
borrower_delta: int256 = principal_delta - convert(interest, int256) - convert(borrower_broker_fee_amount, int256) + convert(borrower_compensation, int256)
current_lender_delta: int256 = convert(loan.amount + interest + borrower_broker_fee_amount + offer.offer.broker_upfront_fee_amount, int256) - convert(total_upfront_fees + settlement_fees_total + borrower_compensation, int256)
new_lender_delta_abs: uint256 = offer.offer.principal - offer.offer.origination_fee_amount + offer.offer.broker_upfront_fee_amount
assert borrower_delta >= 0, "borrower delta < 0"
if loan.lender != offer.offer.lender:
assert current_lender_delta >= 0, "lender delta < 0"
self._receive_funds(offer.offer.lender, new_lender_delta_abs)
if current_lender_delta > 0:
self._send_funds(loan.lender, convert(current_lender_delta, uint256))
else:
lender_delta: int256 = current_lender_delta - convert(new_lender_delta_abs, int256)
# cant have lender delta > 0 and borrower delta >= 0
assert lender_delta <= 0, "lender delta > 0"
if lender_delta < 0:
self._receive_funds(loan.lender, convert(-1 * lender_delta, uint256))
if borrower_delta > 0:
self._send_funds(loan.borrower, convert(borrower_delta, uint256))
for fee in settlement_fees:
self._send_funds(fee.wallet, fee.amount)
for fee in new_loan_fees:
if fee.type != FeeType.ORIGINATION_FEE and fee.upfront_amount > 0:
self._send_funds(fee.wallet, fee.upfront_amount)
offer_id: bytes32 = self._compute_signed_offer_id(offer)
new_loan: Loan = Loan({
id: empty(bytes32),
offer_id: offer_id,
offer_tracing_id: offer.offer.tracing_id,
amount: offer.offer.principal,
interest: offer.offer.interest,
payment_token: offer.offer.payment_token,
maturity: block.timestamp + offer.offer.duration,
start_time: block.timestamp,
borrower: loan.borrower,
lender: offer.offer.lender,
collateral_contract: collection_status.contract,
collateral_token_id: loan.collateral_token_id,
fees: new_loan_fees,
pro_rata: offer.offer.pro_rata,
delegate: loan.delegate
})
new_loan.id = self._compute_loan_id(new_loan)
assert self.loans[new_loan.id] == empty(bytes32), "loan already exists"
self.loans[new_loan.id] = self._loan_state_hash(new_loan)
log LoanReplacedByLender(
new_loan.id,
new_loan.amount,
new_loan.interest,
new_loan.payment_token,
new_loan.maturity,
new_loan.start_time,
new_loan.collateral_contract,
new_loan.collateral_token_id,
new_loan.borrower,
new_loan.lender,
new_loan.fees,
new_loan.pro_rata,
loan.id,
loan.amount,
interest,
settlement_fees,
borrower_compensation,
offer_id,
offer.offer.tracing_id
)
return new_loan.id
@external
def revoke_offer(offer: SignedOffer):
"""
@notice Revoke an offer.
@param offer The signed offer to be revoked.
"""
assert self._check_user(offer.offer.lender), "not lender"
assert offer.offer.expiration > block.timestamp, "offer expired"
assert self._is_offer_signed_by_lender(offer, offer.offer.lender), "offer not signed by lender"
offer_id: bytes32 = self._compute_signed_offer_id(offer)
assert not self.revoked_offers[offer_id], "offer already revoked"
self._revoke_offer(offer_id, offer)
@external
def claim_pending_transfers():
assert self.pending_transfers[msg.sender] > 0, "no pending transfers"
_amount: uint256 = self.pending_transfers[msg.sender]
self.pending_transfers[msg.sender] = 0
assert IERC20(payment_token).transfer(msg.sender, _amount), "error sending funds"
log PendingTransfersClaimed(msg.sender, _amount)
@view
@external
def onERC721Received(_operator: address, _from: address, _tokenId: uint256, _data: Bytes[1024]) -> bytes4:
"""
@notice ERC721 token receiver callback.
@dev Returns the ERC721 receiver callback selector.
@param _operator The address which called `safeTransferFrom` function.
@param _from The address which previously owned the token.
@param _tokenId The NFT identifier which is being transferred.
@param _data Additional data with no specified format.
@return The ERC721 receiver callback selector.
"""
return method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes4)
# Internal functions
@pure
@internal
def _compute_loan_id(loan: Loan) -> bytes32:
return keccak256(concat(
convert(loan.borrower, bytes32),
convert(loan.lender, bytes32),
convert(loan.start_time, bytes32),
convert(loan.collateral_contract, bytes32),
convert(loan.collateral_token_id, bytes32),
))
@pure
@internal
def _compute_signed_offer_id(offer: SignedOffer) -> bytes32:
return keccak256(concat(
convert(offer.signature.v, bytes32),
convert(offer.signature.r, bytes32),
convert(offer.signature.s, bytes32),
))
@internal
def _check_and_update_offer_state(offer: SignedOffer):
offer_id: bytes32 = self._compute_signed_offer_id(offer)
assert not self.revoked_offers[offer_id], "offer revoked"
count: uint256 = self.offer_count[offer.offer.tracing_id]
assert count < offer.offer.size, "offer fully utilized"
self.offer_count[offer.offer.tracing_id] = count + 1
if offer.offer.offer_type == OfferType.TOKEN:
self._revoke_offer(offer_id, offer)
@internal
def _revoke_offer(offer_id: bytes32, offer: SignedOffer):
self.revoked_offers[offer_id] = True
log OfferRevoked(
offer_id,
offer.offer.lender,
offer.offer.collection_key_hash,
offer.offer.offer_type,
)
@internal
def _reduce_offer_count(tracing_id: bytes32):
self.offer_count[tracing_id] -= 1
@view
@internal
def _is_loan_valid(loan: Loan) -> bool:
return self.loans[loan.id] == self._loan_state_hash(loan)
@pure
@internal
def _loan_state_hash(loan: Loan) -> bytes32:
return keccak256(_abi_encode(loan))
@internal
def _is_offer_signed_by_lender(signed_offer: SignedOffer, lender: address) -> bool:
return ecrecover(
keccak256(
concat(
convert("\x19\x01", Bytes[2]),
_abi_encode(
offer_sig_domain_separator,
keccak256(_abi_encode(OFFER_TYPE_HASH, signed_offer.offer))
)
)
),
signed_offer.signature.v,
signed_offer.signature.r,
signed_offer.signature.s
) == lender
@internal
def _get_loan_fees(offer: Offer, borrower_broker_upfront_fee_amount: uint256, borrower_broker_settlement_fee_bps: uint256, borrower_broker: address) -> DynArray[Fee, MAX_FEES]:
fees: DynArray[Fee, MAX_FEES] = []
if offer.origination_fee_amount > 0:
assert offer.origination_fee_amount <= offer.principal, "origination fee gt principal"
if offer.broker_settlement_fee_bps > 0 or offer.broker_upfront_fee_amount > 0:
assert offer.broker_address != empty(address), "broker fee without address"
if borrower_broker_upfront_fee_amount > 0 or borrower_broker_settlement_fee_bps > 0:
assert borrower_broker != empty(address), "broker fee without address"
assert offer.broker_settlement_fee_bps <= max_lender_broker_settlement_fee, "lender broker fee exceeds max"
assert borrower_broker_settlement_fee_bps <= max_borrower_broker_settlement_fee, "borrower broker fee exceeds max"
assert self.protocol_settlement_fee + offer.broker_settlement_fee_bps <= BPS, "settlement fees gt principal"
fees.append(Fee({
type: FeeType.PROTOCOL_FEE,
upfront_amount: self.protocol_upfront_fee * offer.principal / BPS,
interest_bps: self.protocol_settlement_fee,
wallet: self.protocol_wallet
}))
fees.append(Fee({
type: FeeType.ORIGINATION_FEE,
upfront_amount: offer.origination_fee_amount,
interest_bps: 0,
wallet: offer.lender
}))
fees.append(Fee({
type: FeeType.LENDER_BROKER_FEE,
upfront_amount: offer.broker_upfront_fee_amount,
interest_bps: offer.broker_settlement_fee_bps,
wallet: offer.broker_address
}))
fees.append(Fee({
type: FeeType.BORROWER_BROKER_FEE,
upfront_amount: borrower_broker_upfront_fee_amount,
interest_bps: borrower_broker_settlement_fee_bps,
wallet: borrower_broker
}))
return fees
@internal
def _get_settlement_fees(loan: Loan, settlement_interest: uint256) -> (DynArray[FeeAmount, MAX_FEES], uint256, uint256):
total: uint256 = 0
settlement_fees: DynArray[FeeAmount, MAX_FEES] = []
borrower_broker_fee_amount: uint256 = 0
for fee in loan.fees:
if fee.interest_bps > 0:
fee_amount: uint256 = settlement_interest * fee.interest_bps / BPS
settlement_fees.append(FeeAmount({type: fee.type, amount: fee_amount, wallet: fee.wallet}))
total += fee_amount
if fee.type == FeeType.BORROWER_BROKER_FEE:
borrower_broker_fee_amount = fee_amount
return (settlement_fees, total, borrower_broker_fee_amount)
@internal
def _compute_settlement_interest(loan: Loan) -> uint256:
if loan.pro_rata:
return loan.interest * (block.timestamp - loan.start_time) / (loan.maturity - loan.start_time)
else:
return loan.interest
@internal
def _compute_max_interest_delta(loan: Loan, offer: Offer, interest: uint256, borrower_broker_fee_amount: uint256) -> uint256:
"""
Computes the maximum interest difference between the new offer and the current loan.
That max difference can be reached either at the refinance timestamp or at the original loan maturity.
The difference can never be negative because at the refinance timestamp the delta is just the offer interest.
"""
borrower_broker_fee_bps: uint256 = 0
for fee in loan.fees:
if fee.type == FeeType.BORROWER_BROKER_FEE:
borrower_broker_fee_bps = fee.interest_bps
delta_at_refinance: uint256 = 0 if offer.pro_rata else offer.interest
borrower_broker_fee_delta_at_maturity: uint256 = (loan.interest - interest) * borrower_broker_fee_bps / BPS if offer.pro_rata else 0
loan_interest_delta_at_maturity: uint256 = loan.interest - interest
offer_interest_at_loan_maturity: uint256 = offer.interest * (loan.maturity - block.timestamp) / offer.duration if offer.pro_rata else offer.interest
return convert(max(
convert(delta_at_refinance, int256),
convert(offer_interest_at_loan_maturity, int256) - convert(loan_interest_delta_at_maturity, int256) - convert(borrower_broker_fee_delta_at_maturity, int256)
), uint256)
@internal
def _set_delegation(_wallet: address, _collateral_address: address, _token_id: uint256, _value: bool):
delegation_registry.delegateERC721(_wallet, _collateral_address, _token_id, empty(bytes32), _value)
@internal
def _store_punk(_wallet: address, _collateralAddress: address, _tokenId: uint256):
offer: PunkOffer = CryptoPunksMarket(_collateralAddress).punksOfferedForSale(_tokenId)
assert offer.isForSale, "collateral not for sale"
assert offer.punkIndex == _tokenId, "collateral with wrong punkIndex"
assert offer.seller == _wallet, "collateral now owned by wallet"
assert offer.minValue == 0, "collateral offer is not zero"
assert offer.onlySellTo == empty(address) or offer.onlySellTo == self, "collateral buying not authorized"
CryptoPunksMarket(_collateralAddress).buyPunk(_tokenId)
@internal
def _store_erc721(_wallet: address, _collateralAddress: address, _tokenId: uint256):
IERC721(_collateralAddress).safeTransferFrom(_wallet, self, _tokenId, b"")
@internal
def _transfer_punk(_wallet: address, _collateralAddress: address, _tokenId: uint256):
assert self._punk_owner(_collateralAddress, _tokenId) == self, "collateral not owned by vault"
CryptoPunksMarket(_collateralAddress).transferPunk(_wallet, _tokenId)
@internal
def _transfer_erc721(_wallet: address, _collateralAddress: address, _tokenId: uint256):
assert self._erc721_owner(_collateralAddress, _tokenId) == self, "collateral not owned by vault"
IERC721(_collateralAddress).safeTransferFrom(self, _wallet, _tokenId, b"")
@internal
def _transfer_collateral(wallet: address, collateral_contract: address, token_id: uint256):
if self._is_punk(collateral_contract):
self._transfer_punk(wallet, collateral_contract, token_id)
else:
self._transfer_erc721(wallet, collateral_contract, token_id)
@internal
def _send_funds(_to: address, _amount: uint256):
success: bool = False
response: Bytes[32] = b""
success, response = raw_call(
payment_token,
_abi_encode(_to, _amount, method_id=method_id("transfer(address,uint256)")),
max_outsize=32,
revert_on_failure=False
)
if not success or not convert(response, bool):
log TransferFailed(_to, _amount)
self.pending_transfers[_to] += _amount
@internal
def _receive_funds(_from: address, _amount: uint256):
assert IERC20(payment_token).transferFrom(_from, self, _amount), "transferFrom failed"
@internal
def _transfer_funds(_from: address, _to: address, _amount: uint256):
assert IERC20(payment_token).transferFrom(_from, _to, _amount), "transferFrom failed"
@pure
@internal
def _is_punk(_collateralAddress: address) -> bool:
return _collateralAddress == cryptopunks.address
@view
@internal
def _punk_owner(_collateralAddress: address, _tokenId: uint256) -> address:
return CryptoPunksMarket(_collateralAddress).punkIndexToAddress(_tokenId)
@view
@internal
def _erc721_owner(_collateralAddress: address, _tokenId: uint256) -> address:
return IERC721(_collateralAddress).ownerOf(_tokenId)
@view
@internal
def _is_punk_approved_for_vault(_borrower: address, _collateralAddress: address, _tokenId: uint256) -> bool:
offer: PunkOffer = cryptopunks.punksOfferedForSale(_tokenId)
return (
offer.isForSale and
offer.punkIndex == _tokenId and
offer.minValue == 0 and
(offer.onlySellTo == empty(address) or offer.onlySellTo == self)
)
@view
@internal
def _is_erc721_approved_for_vault(_borrower: address, _collateralAddress: address, _tokenId: uint256) -> bool:
return IERC721(_collateralAddress).isApprovedForAll(_borrower, self) or IERC721(_collateralAddress).getApproved(_tokenId) == self
@internal
def _store_collateral(wallet: address, collateral_contract: address, token_id: uint256):
assert wallet != empty(address), "addr is the zero addr"
assert collateral_contract != empty(address), "collat addr is the zero addr"
if self._is_punk(collateral_contract):
assert self._punk_owner(collateral_contract, token_id) == wallet, "collateral not owned by wallet"
assert self._is_punk_approved_for_vault(wallet, collateral_contract, token_id), "transfer is not approved"
self._store_punk(wallet, collateral_contract, token_id)
else:
assert self._erc721_owner(collateral_contract, token_id) == wallet, "collateral not owned by wallet"
assert self._is_erc721_approved_for_vault(wallet, collateral_contract, token_id), "transfer is not approved"
self._store_erc721(wallet, collateral_contract, token_id)
@internal
def _check_user(user: address) -> bool:
return msg.sender == user or (self.authorized_proxies[msg.sender] and user == tx.origin)
@internal
def _validate_token_ids(
offer: Offer,
collateral_token_id: uint256,
collection_status: CollectionStatus,
collateral_proof: DynArray[bytes32, PROOF_MAX_SIZE]
):
assert collection_status.contract != empty(address), "collateral not whitelisted"
if offer.offer_type == OfferType.TOKEN:
assert offer.token_id == collateral_token_id, "token id not in offer"
elif offer.offer_type == OfferType.COLLECTION:
assert collateral_token_id >= offer.token_range_min, "tokenid below offer range"
assert collateral_token_id <= offer.token_range_max, "tokenid above offer range"
else:
_hash: bytes32 = keccak256(_abi_encode(collection_status.contract, offer.trait_hash, collateral_token_id))
for p in collateral_proof:
_hash = keccak256(_abi_encode(convert(keccak256(_hash), uint256) ^ convert(keccak256(p), uint256)))
assert collection_status.trait_root == _hash, "proof invalid"Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"name":"LoanCreated","inputs":[{"name":"id","type":"bytes32","indexed":false},{"name":"amount","type":"uint256","indexed":false},{"name":"interest","type":"uint256","indexed":false},{"name":"payment_token","type":"address","indexed":false},{"name":"maturity","type":"uint256","indexed":false},{"name":"start_time","type":"uint256","indexed":false},{"name":"borrower","type":"address","indexed":false},{"name":"lender","type":"address","indexed":false},{"name":"collateral_contract","type":"address","indexed":false},{"name":"collateral_token_id","type":"uint256","indexed":false},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}],"indexed":false},{"name":"pro_rata","type":"bool","indexed":false},{"name":"offer_id","type":"bytes32","indexed":false},{"name":"offer_tracing_id","type":"bytes32","indexed":false},{"name":"delegate","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"LoanReplaced","inputs":[{"name":"id","type":"bytes32","indexed":false},{"name":"amount","type":"uint256","indexed":false},{"name":"interest","type":"uint256","indexed":false},{"name":"payment_token","type":"address","indexed":false},{"name":"maturity","type":"uint256","indexed":false},{"name":"start_time","type":"uint256","indexed":false},{"name":"collateral_contract","type":"address","indexed":false},{"name":"collateral_token_id","type":"uint256","indexed":false},{"name":"borrower","type":"address","indexed":false},{"name":"lender","type":"address","indexed":false},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}],"indexed":false},{"name":"pro_rata","type":"bool","indexed":false},{"name":"original_loan_id","type":"bytes32","indexed":false},{"name":"paid_principal","type":"uint256","indexed":false},{"name":"paid_interest","type":"uint256","indexed":false},{"name":"paid_settlement_fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"wallet","type":"address"}],"indexed":false},{"name":"offer_id","type":"bytes32","indexed":false},{"name":"offer_tracing_id","type":"bytes32","indexed":false}],"anonymous":false,"type":"event"},{"name":"LoanReplacedByLender","inputs":[{"name":"id","type":"bytes32","indexed":false},{"name":"amount","type":"uint256","indexed":false},{"name":"interest","type":"uint256","indexed":false},{"name":"payment_token","type":"address","indexed":false},{"name":"maturity","type":"uint256","indexed":false},{"name":"start_time","type":"uint256","indexed":false},{"name":"collateral_contract","type":"address","indexed":false},{"name":"collateral_token_id","type":"uint256","indexed":false},{"name":"borrower","type":"address","indexed":false},{"name":"lender","type":"address","indexed":false},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}],"indexed":false},{"name":"pro_rata","type":"bool","indexed":false},{"name":"original_loan_id","type":"bytes32","indexed":false},{"name":"paid_principal","type":"uint256","indexed":false},{"name":"paid_interest","type":"uint256","indexed":false},{"name":"paid_settlement_fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"wallet","type":"address"}],"indexed":false},{"name":"borrower_compensation","type":"uint256","indexed":false},{"name":"offer_id","type":"bytes32","indexed":false},{"name":"offer_tracing_id","type":"bytes32","indexed":false}],"anonymous":false,"type":"event"},{"name":"LoanPaid","inputs":[{"name":"id","type":"bytes32","indexed":false},{"name":"borrower","type":"address","indexed":false},{"name":"lender","type":"address","indexed":false},{"name":"payment_token","type":"address","indexed":false},{"name":"paid_principal","type":"uint256","indexed":false},{"name":"paid_interest","type":"uint256","indexed":false},{"name":"paid_settlement_fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"wallet","type":"address"}],"indexed":false}],"anonymous":false,"type":"event"},{"name":"LoanCollateralClaimed","inputs":[{"name":"id","type":"bytes32","indexed":false},{"name":"borrower","type":"address","indexed":false},{"name":"lender","type":"address","indexed":false},{"name":"collateral_contract","type":"address","indexed":false},{"name":"collateral_token_id","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"OfferRevoked","inputs":[{"name":"offer_id","type":"bytes32","indexed":false},{"name":"lender","type":"address","indexed":false},{"name":"collection_key_hash","type":"bytes32","indexed":false},{"name":"offer_type","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"OwnerProposed","inputs":[{"name":"owner","type":"address","indexed":false},{"name":"proposed_owner","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"OwnershipTransferred","inputs":[{"name":"old_owner","type":"address","indexed":false},{"name":"new_owner","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ProtocolFeeSet","inputs":[{"name":"old_upfront_fee","type":"uint256","indexed":false},{"name":"old_settlement_fee","type":"uint256","indexed":false},{"name":"new_upfront_fee","type":"uint256","indexed":false},{"name":"new_settlement_fee","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"ProtocolWalletChanged","inputs":[{"name":"old_wallet","type":"address","indexed":false},{"name":"new_wallet","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ProxyAuthorizationChanged","inputs":[{"name":"proxy","type":"address","indexed":false},{"name":"value","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"TransferFailed","inputs":[{"name":"_to","type":"address","indexed":false},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"PendingTransfersClaimed","inputs":[{"name":"_to","type":"address","indexed":false},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_payment_token","type":"address"},{"name":"_p2p_control","type":"address"},{"name":"_delegation_registry","type":"address"},{"name":"_cryptopunks","type":"address"},{"name":"_protocol_upfront_fee","type":"uint256"},{"name":"_protocol_settlement_fee","type":"uint256"},{"name":"_protocol_wallet","type":"address"},{"name":"_max_protocol_upfront_fee","type":"uint256"},{"name":"_max_protocol_settlement_fee","type":"uint256"},{"name":"_max_lender_broker_settlement_fee","type":"uint256"},{"name":"_max_borrower_broker_settlement_fee","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_protocol_fee","inputs":[{"name":"protocol_upfront_fee","type":"uint256"},{"name":"protocol_settlement_fee","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"change_protocol_wallet","inputs":[{"name":"new_protocol_wallet","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_proxy_authorization","inputs":[{"name":"_proxy","type":"address"},{"name":"_value","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"propose_owner","inputs":[{"name":"_address","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_ownership","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"create_loan","inputs":[{"name":"offer","type":"tuple","components":[{"name":"offer","type":"tuple","components":[{"name":"principal","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"duration","type":"uint256"},{"name":"origination_fee_amount","type":"uint256"},{"name":"broker_upfront_fee_amount","type":"uint256"},{"name":"broker_settlement_fee_bps","type":"uint256"},{"name":"broker_address","type":"address"},{"name":"offer_type","type":"uint256"},{"name":"token_id","type":"uint256"},{"name":"token_range_min","type":"uint256"},{"name":"token_range_max","type":"uint256"},{"name":"collection_key_hash","type":"bytes32"},{"name":"trait_hash","type":"bytes32"},{"name":"expiration","type":"uint256"},{"name":"lender","type":"address"},{"name":"pro_rata","type":"bool"},{"name":"size","type":"uint256"},{"name":"tracing_id","type":"bytes32"}]},{"name":"signature","type":"tuple","components":[{"name":"v","type":"uint256"},{"name":"r","type":"uint256"},{"name":"s","type":"uint256"}]}]},{"name":"collateral_token_id","type":"uint256"},{"name":"collateral_proof","type":"bytes32[]"},{"name":"delegate","type":"address"},{"name":"borrower_broker_upfront_fee_amount","type":"uint256"},{"name":"borrower_broker_settlement_fee_bps","type":"uint256"},{"name":"borrower_broker","type":"address"}],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"nonpayable","type":"function","name":"settle_loan","inputs":[{"name":"loan","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"offer_id","type":"bytes32"},{"name":"offer_tracing_id","type":"bytes32"},{"name":"amount","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"maturity","type":"uint256"},{"name":"start_time","type":"uint256"},{"name":"borrower","type":"address"},{"name":"lender","type":"address"},{"name":"collateral_contract","type":"address"},{"name":"collateral_token_id","type":"uint256"},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}]},{"name":"pro_rata","type":"bool"},{"name":"delegate","type":"address"}]}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_defaulted_loan_collateral","inputs":[{"name":"loan","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"offer_id","type":"bytes32"},{"name":"offer_tracing_id","type":"bytes32"},{"name":"amount","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"maturity","type":"uint256"},{"name":"start_time","type":"uint256"},{"name":"borrower","type":"address"},{"name":"lender","type":"address"},{"name":"collateral_contract","type":"address"},{"name":"collateral_token_id","type":"uint256"},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}]},{"name":"pro_rata","type":"bool"},{"name":"delegate","type":"address"}]}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"replace_loan","inputs":[{"name":"loan","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"offer_id","type":"bytes32"},{"name":"offer_tracing_id","type":"bytes32"},{"name":"amount","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"maturity","type":"uint256"},{"name":"start_time","type":"uint256"},{"name":"borrower","type":"address"},{"name":"lender","type":"address"},{"name":"collateral_contract","type":"address"},{"name":"collateral_token_id","type":"uint256"},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}]},{"name":"pro_rata","type":"bool"},{"name":"delegate","type":"address"}]},{"name":"offer","type":"tuple","components":[{"name":"offer","type":"tuple","components":[{"name":"principal","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"duration","type":"uint256"},{"name":"origination_fee_amount","type":"uint256"},{"name":"broker_upfront_fee_amount","type":"uint256"},{"name":"broker_settlement_fee_bps","type":"uint256"},{"name":"broker_address","type":"address"},{"name":"offer_type","type":"uint256"},{"name":"token_id","type":"uint256"},{"name":"token_range_min","type":"uint256"},{"name":"token_range_max","type":"uint256"},{"name":"collection_key_hash","type":"bytes32"},{"name":"trait_hash","type":"bytes32"},{"name":"expiration","type":"uint256"},{"name":"lender","type":"address"},{"name":"pro_rata","type":"bool"},{"name":"size","type":"uint256"},{"name":"tracing_id","type":"bytes32"}]},{"name":"signature","type":"tuple","components":[{"name":"v","type":"uint256"},{"name":"r","type":"uint256"},{"name":"s","type":"uint256"}]}]},{"name":"collateral_proof","type":"bytes32[]"},{"name":"borrower_broker_upfront_fee_amount","type":"uint256"},{"name":"borrower_broker_settlement_fee_bps","type":"uint256"},{"name":"borrower_broker","type":"address"}],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"nonpayable","type":"function","name":"replace_loan_lender","inputs":[{"name":"loan","type":"tuple","components":[{"name":"id","type":"bytes32"},{"name":"offer_id","type":"bytes32"},{"name":"offer_tracing_id","type":"bytes32"},{"name":"amount","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"maturity","type":"uint256"},{"name":"start_time","type":"uint256"},{"name":"borrower","type":"address"},{"name":"lender","type":"address"},{"name":"collateral_contract","type":"address"},{"name":"collateral_token_id","type":"uint256"},{"name":"fees","type":"tuple[]","components":[{"name":"type","type":"uint256"},{"name":"upfront_amount","type":"uint256"},{"name":"interest_bps","type":"uint256"},{"name":"wallet","type":"address"}]},{"name":"pro_rata","type":"bool"},{"name":"delegate","type":"address"}]},{"name":"offer","type":"tuple","components":[{"name":"offer","type":"tuple","components":[{"name":"principal","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"duration","type":"uint256"},{"name":"origination_fee_amount","type":"uint256"},{"name":"broker_upfront_fee_amount","type":"uint256"},{"name":"broker_settlement_fee_bps","type":"uint256"},{"name":"broker_address","type":"address"},{"name":"offer_type","type":"uint256"},{"name":"token_id","type":"uint256"},{"name":"token_range_min","type":"uint256"},{"name":"token_range_max","type":"uint256"},{"name":"collection_key_hash","type":"bytes32"},{"name":"trait_hash","type":"bytes32"},{"name":"expiration","type":"uint256"},{"name":"lender","type":"address"},{"name":"pro_rata","type":"bool"},{"name":"size","type":"uint256"},{"name":"tracing_id","type":"bytes32"}]},{"name":"signature","type":"tuple","components":[{"name":"v","type":"uint256"},{"name":"r","type":"uint256"},{"name":"s","type":"uint256"}]}]},{"name":"collateral_proof","type":"bytes32[]"}],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"nonpayable","type":"function","name":"revoke_offer","inputs":[{"name":"offer","type":"tuple","components":[{"name":"offer","type":"tuple","components":[{"name":"principal","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"payment_token","type":"address"},{"name":"duration","type":"uint256"},{"name":"origination_fee_amount","type":"uint256"},{"name":"broker_upfront_fee_amount","type":"uint256"},{"name":"broker_settlement_fee_bps","type":"uint256"},{"name":"broker_address","type":"address"},{"name":"offer_type","type":"uint256"},{"name":"token_id","type":"uint256"},{"name":"token_range_min","type":"uint256"},{"name":"token_range_max","type":"uint256"},{"name":"collection_key_hash","type":"bytes32"},{"name":"trait_hash","type":"bytes32"},{"name":"expiration","type":"uint256"},{"name":"lender","type":"address"},{"name":"pro_rata","type":"bool"},{"name":"size","type":"uint256"},{"name":"tracing_id","type":"bytes32"}]},{"name":"signature","type":"tuple","components":[{"name":"v","type":"uint256"},{"name":"r","type":"uint256"},{"name":"s","type":"uint256"}]}]}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_pending_transfers","inputs":[],"outputs":[]},{"stateMutability":"view","type":"function","name":"onERC721Received","inputs":[{"name":"_operator","type":"address"},{"name":"_from","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"outputs":[{"name":"","type":"bytes4"}]},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"proposed_owner","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"payment_token","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"loans","inputs":[{"name":"arg0","type":"bytes32"}],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"view","type":"function","name":"delegation_registry","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"cryptopunks","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"p2p_control","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"protocol_wallet","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"protocol_upfront_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"protocol_settlement_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"max_protocol_upfront_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"max_protocol_settlement_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"max_lender_broker_settlement_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"max_borrower_broker_settlement_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"offer_count","inputs":[{"name":"arg0","type":"bytes32"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"revoked_offers","inputs":[{"name":"arg0","type":"bytes32"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"authorized_proxies","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"pending_transfers","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"VERSION","inputs":[],"outputs":[{"name":"","type":"string"}]}]Contract Creation Code
615bd55150346103fd576020615eed5f395f518060a01c6103fd576040526020615f0d5f395f518060a01c6103fd576060526020615f2d5f395f518060a01c6103fd576080526020615f4d5f395f518060a01c6103fd5760a0526020615fad5f395f518060a01c6103fd5760c05260c0516100d257601a60e0527f77616c6c657420697320746865207a65726f20616464726573730000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b60405161013757601560e0527f7061796d656e7420746f6b656e206973207a65726f00000000000000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b60605161019c57601360e0527f70327020636f6e74726f6c206973207a65726f000000000000000000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b60805161020157601b60e0527f64656c65676174696f6e207265676973747279206973207a65726f00000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b6020615fcd5f395f516020615f6d5f395f51111561027757601760e0527f757066726f6e74206665652065786365656473206d61780000000000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b6020615fed5f395f516020615f8d5f395f5111156102ed57601a60e0527f736574746c656d656e74206665652065786365656473206d61780000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b335f55604051615ad552606051615b3552608051615af55260a051615b15526020615fcd5f395f51615b55526020615fed5f395f51615b7552602061600d5f395f51615b9552602061602d5f395f51615bb5526020615f6d5f395f516004556020615f8d5f395f5160055560c0516003557f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f610100527f8cfe527f02f4c08ff029d82debdef92d77938d41c05f0919d733c8091bf9b8d8610120527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6610140524661016052306101805260a060e05260e0805160208201209050615bd552615ad561040161000039615bf5610000f35b5f80fd5f3560e01c6002601f820660011b615a9701601e395f51565b638da5cb5b81186100335734615a93575f5460405260206040f35b6361acb5598118613d0857602436103417615a935760076004356020525f5260405f205460405260206040f3613d08565b63885753de81186100805734615a935760015460405260206040f35b63ffa1ad748118613d085734615a935760208060805260176040527f5032504c656e64696e674e6674732e323032343130303200000000000000000060605260408160800181518152602082015160208201528051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f3613d08565b63331c658781186101205734615a93576020615ad560403960206040f35b6305107f058118613d085761022436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a9357801561023e57905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a9357606083015250506001018181186101ee575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a935761102052506103e06108606103e0610c6060045afa50610288611040615308565b611040516102f557600c611060527f696e76616c6964206c6f616e00000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b610d20514211610364576012611040527f6c6f616e206e6f742064656661756c74656400000000000000000000000000006110605261104050611040518061106001601f825f031636823750506308c379a061100052602061102052601f19601f61104051011660440161101cfd5b610d805160405261037661104061533d565b611040516103e357600a611060527f6e6f74206c656e646572000000000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b5f6002610c60516020525f5260405f2055610d805161022052610da05161024052610dc0516102605261041461588c565b611020511561043e5761102051604052610da051606052610dc0516080525f60a05261043e6152b1565b7f4a55c2facef4f87dd498aace39997457e1fc66968956bfe3ac7f20f736e77e74610c605161104052610d605161106052610d805161108052610da0516110a052610dc0516110c05260a0611040a100613d08565b63c4a9081581186104c057602436103417615a935760026004356020525f5260405f205460405260206040f35b639544fa7c8118613d0857604436103417615a93576004358060a01c615a93576040526024358060011c615a93576060525f543318156105565760096080527f6e6f74206f776e6572000000000000000000000000000000000000000000000060a0526080506080518060a001601f825f031636823750506308c379a06040526020606052601f19601f6080510116604401605cfd5b60605160086040516020525f5260405f20557f5e09e79221e29a6d762b708b6fa399e730dfc027f946b2e81a31d849b2fb1fa960405160805260605160a05260406080a100613d08565b63e5107ed781186105be5734615a93576020615af560403960206040f35b63c2a5022b8118613d0857604436103417615a93575f543318156106375760096040527f6e6f74206f776e6572000000000000000000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6020615b555f395f5160043511156106a45760176040527f757066726f6e74206665652065786365656473206d617800000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6020615b755f395f51602435111561071157601a6040527f736574746c656d656e74206665652065786365656473206d617800000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b7f4bfb2e8697c06dccd3777bdd9b4dab854905ca53b2a56bb47882c744729729d46004546040526005546060526040600460803760806040a160043560045560243560055500613d08565b635556eda98118613d085734615a93576020615b1560403960206040f3613d08565b637719e9ea811861079c5734615a93576020615b3560403960206040f35b639274bbcd8118613d0857602436103417615a93576004358060a01c615a935760405260096040516020525f5260405f205460605260206060f3613d08565b6367db749981186107f75734615a935760035460405260206040f35b63f8c266298118613d085734615a93576020615b9560403960206040f3613d08565b6358e7783781186108355734615a935760045460405260206040f35b63f7a79a028118613d085734615a93576001543318156108aa5760166040527f6e6f74207468652070726f706f736564206f776e65720000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f5460405260015460605260406040a1335f555f60015500613d08565b6361dd0b8b8118613d085734615a935760055460405260206040f3613d08565b6350d0d5ad8118613d085734615a93576020615b5560403960206040f3613d08565b6387c8f69481186109485734615a93576020615b7560403960206040f35b63a1c7a5678118613d08576103a436103417615a935760406004610860376044358060a01c615a93576108a0526064356108c052606060846108e03760e4358060a01c615a935761094052610104358060031c615a935761096052610124356109805260a06101446109a0376101e4358060a01c615a9357610a4052610204358060011c615a9357610a60526040610224610a80376060610264610ac0376102e4356004016020813511615a9357803560208160051b018083610b2037505050610304358060a01c615a9357610f4052610364358060a01c615a9357610f60526102c060406102c061086060045afa50610a405161030052610a4b610f80613d0c565b610f8051610ab857601a610fa0527f6f66666572206e6f74207369676e6564206279206c656e646572000000000000610fc052610fa050610fa05180610fc001601f825f031636823750506308c379a0610f60526020610f8052601f19601f610fa0510116604401610f7cfd5b42610a205111610b2757600d610f80527f6f66666572206578706972656400000000000000000000000000000000000000610fa052610f8050610f805180610fa001601f825f031636823750506308c379a0610f40526020610f6052601f19601f610f80510116604401610f5cfd5b6020615ad55f395f516108a0511815610b9f576015610f80527f696e76616c6964207061796d656e7420746f6b656e0000000000000000000000610fa052610f8050610f805180610fa001601f825f031636823750506308c379a0610f40526020610f6052601f19601f610f80510116604401610f5cfd5b610860516108e0511115610c1257601c610f80527f6f726967696e6174696f6e20666565206774207072696e636970616c00000000610fa052610f8050610f805180610fa001601f825f031636823750506308c379a0610f40526020610f6052601f19601f610f80510116604401610f5cfd5b6020615b355f395f516356108f8a610fc0526109e051610fe0526040610fc06024610fdc5f855af1610c46573d5f5f3e3d5ffd5b60403d10615a9357610fc0518060a01c615a935761102052610fe0516110405261102090508051610f80526020810151610fa05250610260604061026061086060045afa506102c4356102a052610f80516102c052610fa0516102e052610b205160208160051b018061030082610b2060045afa505050610cc5613e1f565b610260604061026061086060045afa5060406103246102a037610f60516102e052610cf16111e0614104565b6111e0805160208160071b0180610fc0828560045afa505050505f6111e0525f610fc05160048111615a93578015610d7457905b8060071b610fe001805161120052602081015161122052604081015161124052606081015161126052506111e05161122051808201828110615a9357905090506111e052600101818118610d25575b50506102c060406102c061086060045afa50610d9161122061452b565b61122051611200525f611220526112005161124052610aa051611260526108605161128052610880516112a0526108a0516112c052426108c051808201828110615a9357905090506112e05242611300526008336020525f5260405f2054610df95733610dfb565b325b61132052610a405161134052610f8051611360526102c43561138052610fc05160208160071b01806113a082610fc060045afa505050610a60516115c052610f40516115e0526103e060406103e061122060045afa50610e5c611600614574565b61160051611220526002611220516020525f5260405f205415610ede576013611600527f6c6f616e20616c726561647920657869737473000000000000000000000000006116205261160050611600518061162001601f825f031636823750506308c379a06115c05260206115e052601f19601f6116005101166044016115dcfd5b6102c06103a06102c061086060045afa50610ef7614636565b6103e060406103e061122060045afa50610f126116006147a6565b611600516002611220516020525f5260405f2055611320516102a052611360516102c052611380516102e052610f46614e87565b6113405160405261132051606052611280516111e051808203828111615a93579050905061090051808201828110615a935790509050608052610f876151ed565b5f610fc05160048111615a9357801561100b57905b8060071b610fe0018051611600526020810151611620526040810151611640526060810151611660525060026116005114610fdc57611620511515610fde565b5f5b15611000576113405160405261166051606052611620516080526110006151ed565b600101818118610f9c575b5050610f40511561103857610f40516040526113605160605261138051608052600160a0526110386152b1565b7f6827a33d0a24e36314681156d8d9a7d20d6a0548c169735fe25e00c9d38ac5a96101e0611220516116005261128051611620526112a051611640526112c051611660526112e05161168052611300516116a052611320516116c052611340516116e05261136051611700526113805161172052806117405280611600015f6113a0518083528060071b5f8260048111615a9357801561111457905b8060071b60208701018160071b6113c0018051825260208101516020830152604081015160408301526060810151606083015250506001018181186110d4575b505082016020019150509050810190506115c051611760526112005161178052610aa0516117a052610f40516117c052611600a16020611220f3613d08565b631b0b0c638118613d085734615a93576020615bb560403960206040f3613d08565b63225daa0f8118613d0857602436103417615a935760066004356020525f5260405f205460405260206040f3613d08565b6396069a5f8118613d0857602436103417615a93576004358060a01c615a935760405260086040516020525f5260405f205460605260206060f3613d08565b6372e76f13811861130a57602436103417615a93576004358060a01c615a93576040525f5433181561126d5760096060527f6e6f74206f776e6572000000000000000000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516112d057601a6060527f77616c6c657420697320746865207a65726f206164647265737300000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b7f6defa6e1a7dcc97f459fb552cf25427ab19cd60692b94e4f38660850a6e917e860035460605260405160805260406060a1604051600355005b63c75b6e5e8118613d08576102c436103417615a935760406004610780376044358060a01c615a93576107c0526064356107e052606060846108003760e4358060a01c615a935761086052610104358060031c615a935761088052610124356108a05260a06101446108c0376101e4358060a01c615a935761096052610204358060011c615a93576109805260406102246109a03760606102646109e037610960516040526113ba610a4061533d565b610a405161142757600a610a60527f6e6f74206c656e64657200000000000000000000000000000000000000000000610a8052610a6050610a605180610a8001601f825f031636823750506308c379a0610a20526020610a4052601f19601f610a60510116604401610a3cfd5b42610940511161149657600d610a40527f6f66666572206578706972656400000000000000000000000000000000000000610a6052610a4050610a405180610a6001601f825f031636823750506308c379a0610a00526020610a2052601f19601f610a40510116604401610a1cfd5b6102c060406102c061078060045afa5061096051610300526114b9610a40613d0c565b610a405161152657601a610a60527f6f66666572206e6f74207369676e6564206279206c656e646572000000000000610a8052610a6050610a605180610a8001601f825f031636823750506308c379a0610a20526020610a4052601f19601f610a60510116604401610a3cfd5b6102c060406102c061078060045afa50611541610a6061452b565b610a6051610a40526007610a40516020525f5260405f2054156115c3576015610a60527f6f6666657220616c7265616479207265766f6b65640000000000000000000000610a8052610a6050610a605180610a8001601f825f031636823750506308c379a0610a20526020610a4052601f19601f610a60510116604401610a3cfd5b610a40516040526102c060606102c061078060045afa506115e26145dd565b00613d08565b63bc71771d8118613d0857602436103417615a93576004358060a01c615a93576040525f543318156116705760096060527f6e6f74206f776e6572000000000000000000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516116d35760106060527f5f61646472657373206973207a65726f0000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b7f722cace8a9cbcb7713f3f71015c8c6b59ed317672489140eb6b3fa7f4a139d845f5460605260405160805260406060a160405160015500613d08565b63802d67998118613d085761022436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a9357801561182e57905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a9357606083015250506001018181186117de575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a935761102052506103e06108606103e0610c6060045afa50611878611040615308565b611040516118e557600c611060527f696e76616c6964206c6f616e00000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b610d205142111561195557600e611040527f6c6f616e2064656661756c7465640000000000000000000000000000000000006110605261104050611040518061106001601f825f031636823750506308c379a061100052602061102052601f19601f61104051011660440161101cfd5b610d605160405261196761104061533d565b611040516119d457600c611060527f6e6f7420626f72726f77657200000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b6103e060406103e0610c6060045afa506119ef611060615370565b6110605161104052604036611060375f611220526103e060406103e0610c6060045afa506110405161042052611a266112406153da565b61124080516020606082020180611080828560045afa5050506101a0810151611060526101c081015161122052505f6002610c60516020525f5260405f2055610ca051604052611a746154f5565b610d6051604052610cc05161104051808201828110615a93579050905061122051808201828110615a935790509050606052611aae615517565b610d8051604052610cc05161104051808201828110615a93579050905061106051808203828111615a93579050905061122051808201828110615a935790509050606052611afa6155d6565b5f6110805160048111615a93578015611b5157905b606081026110a001805161124052602081015161126052604081015161128052506112805160405261126051606052611b466155d6565b600101818118611b0f575b5050610d605161022052610da05161024052610dc05161026052611b7361588c565b6110205115611b9d5761102051604052610da051606052610dc0516080525f60a052611b9d6152b1565b7f2aa6f229bb00348f1aa98ab5ab1636a2618696536f698200d76b66a87906eafa60e0610c605161124052610d605161126052610d805161128052610d00516112a052610cc0516112c052611040516112e052806113005280611240015f61108051808352606081025f8260048111615a93578015611c4e57905b606081026020870101606082026110a0018051825260208101516020830152604081015160408301525050600101818118611c18575b50508201602001915050905081019050611240a100613d08565b6313c072ee8118613d085761058436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a93578015611d8657905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a935760608301525050600101818118611d36575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a9357611020525060406024611040376064358060a01c615a9357611080526084356110a052606060a46110c037610104358060a01c615a935761112052610124358060031c615a935761114052610144356111605260a061016461118037610204358060a01c615a935761122052610224358060011c615a93576112405260406102446112603760606102846112a0376102e4356004016020813511615a9357803560208160051b01808361130037505050610344358060a01c615a9357611720526103e06108606103e0610c6060045afa50611e8b611740615308565b61174051611ef857600c611760527f696e76616c6964206c6f616e00000000000000000000000000000000000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b610d6051604052611f0a61174061533d565b61174051611f7757600c611760527f6e6f7420626f72726f77657200000000000000000000000000000000000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b610d2051421115611fe757600e611740527f6c6f616e2064656661756c7465640000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b6102c060406102c061104060045afa50611220516103005261200a611740613d0c565b6117405161207757601a611760527f6f66666572206e6f74207369676e6564206279206c656e6465720000000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b4261120051116120e657600d611740527f6f666665722065787069726564000000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b6020615ad55f395f5161108051181561215e576015611740527f696e76616c6964207061796d656e7420746f6b656e00000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b611040516110c05111156121d157601c611740527f6f726967696e6174696f6e20666565206774207072696e636970616c000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b6020615b355f395f516356108f8a611780526111c0516117a0526040611780602461179c5f855af1612205573d5f5f3e3d5ffd5b60403d10615a9357611780518060a01c615a93576117e0526117a051611800526117e0905080516117405260208101516117605250610260604061026061104060045afa50610dc0516102a052611740516102c052611760516102e0526113005160208160051b01806103008261130060045afa505050612284613e1f565b610da0516117405118156122f757601c611780527f636f6c6c61746572616c20636f6e7472616374206d69736d61746368000000006117a0526117805061178051806117a001601f825f031636823750506308c379a061174052602061176052601f19601f61178051011660440161175cfd5b6102c06103a06102c061104060045afa50612310614636565b610ca05160405261231f6154f5565b611040518060ff1c615a9357610cc0518060ff1c615a93578082038281135f831218615a935790509050611780526103e060406103e0610c6060045afa506123686117c0615370565b6117c0516117a0526040366117c0375f611980526103e060406103e0610c6060045afa506117a0516104205261239f6119a06153da565b6119a0805160206060820201806117e0828560045afa5050506101a08101516117c0526101c08101516119805250610260604061026061104060045afa5060406103046102a037611720516102e0526123f9611bc0614104565b611bc0805160208160071b01806119a0828560045afa505050505f611bc0525f6119a05160048111615a9357801561247c57905b8060071b6119c0018051611be0526020810151611c00526040810151611c20526060810151611c405250611bc051611c0051808201828110615a935790509050611bc05260010181811861242d575b50505f6002610c60516020525f5260405f205561178051611bc0516117a051808201828110615a93579050905061198051808201828110615a9357905090508060ff1c615a93578082038281135f831218615a9357905090506110e0518060ff1c615a93578082018281125f831218615a935790509050611be052610cc0516117a051808201828110615a9357905090506117c051808203828111615a93579050905061198051808201828110615a935790509050611c0052611040516110c051808203828111615a9357905090506110e051808201828110615a935790509050611c20527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611be051136125c057610d6051604052611be051805f03600160ff1b82141582825f03141615615a935790505f8112615a93576060526125c0615517565b61122051610d8051146125fd5761122051604052611c20516060526125e3615517565b610d8051604052611c005160605261266c6155d65661266c565b611c2051611c00511161264457611c2051611c0051101561266c57610d8051604052611c2051611c0051808203828111615a93579050905060605261266c6155175661266c565b610d8051604052611c0051611c2051808203828111615a93579050905060605261266c6155d6565b6001611be0511261269457610d6051604052611be0515f8112615a93576060526126946155d6565b5f6117e05160048111615a935780156126eb57905b60608102611800018051611c40526020810151611c60526040810151611c805250611c8051604052611c60516060526126e06155d6565b6001018181186126a9575b50505f6119a05160048111615a9357801561276a57905b8060071b6119c0018051611c40526020810151611c60526040810151611c80526060810151611ca052506002611c40511461274257611c60511515612744565b5f5b1561275f57611ca051604052611c605160605261275f6155d6565b600101818118612702575b50506102c060406102c061104060045afa50612787611c6061452b565b611c6051611c40525f611c6052611c4051611c805261128051611ca05261104051611cc05261106051611ce05261108051611d0052426110a051808201828110615a935790509050611d205242611d4052610d6051611d605261122051611d805261174051611da052610dc051611dc0526119a05160208160071b0180611de0826119a060045afa505050611240516120005261102051612020526103e060406103e0611c6060045afa5061283d612040614574565b61204051611c60526002611c60516020525f5260405f2054156128bf576013612040527f6c6f616e20616c726561647920657869737473000000000000000000000000006120605261204050612040518061206001601f825f031636823750506308c379a061200052602061202052601f19601f61204051011660440161201cfd5b6103e060406103e0611c6060045afa506128da6120406147a6565b612040516002611c60516020525f5260405f20557fadf0e5d2eb7098352961e41ff94c8d5bd1e0d24910d7c8e7ae147610146fef21610240611c605161204052611cc05161206052611ce05161208052611d00516120a052611d20516120c052611d40516120e052611da05161210052611dc05161212052611d605161214052611d805161216052806121805280612040015f611de0518083528060071b5f8260048111615a935780156129ca57905b8060071b60208701018160071b611e000180518252602081015160208301526040810151604083015260608101516060830152505060010181811861298a575b50508201602001915050905081019050612000516121a052610c60516121c052610cc0516121e0526117a05161220052806122205280612040015f6117e051808352606081025f8260048111615a93578015612a5857905b60608102602087010160608202611800018051825260208101516020830152604081015160408301525050600101818118612a22575b50508201602001915050905081019050611c4051612240526112805161226052612040a16020611c60f3613d08565b63304b74ed8118613d085761052436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a93578015612ba557905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a935760608301525050600101818118612b55575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a9357611020525060406024611040376064358060a01c615a9357611080526084356110a052606060a46110c037610104358060a01c615a935761112052610124358060031c615a935761114052610144356111605260a061016461118037610204358060a01c615a935761122052610224358060011c615a93576112405260406102446112603760606102846112a0376102e4356004016020813511615a9357803560208160051b018083611300375050506103e06108606103e0610c6060045afa50612c9a611720615308565b61172051612d0757600c611740527f696e76616c6964206c6f616e00000000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b610d8051604052612d1961172061533d565b61172051612d8657600a611740527f6e6f74206c656e646572000000000000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b610d2051421115612df657600e611720527f6c6f616e2064656661756c7465640000000000000000000000000000000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b6102c060406102c061104060045afa506112205161030052612e19611720613d0c565b61172051612e8657601a611740527f6f66666572206e6f74207369676e6564206279206c656e6465720000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b426112005111612ef557600d611720527f6f666665722065787069726564000000000000000000000000000000000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b6020615ad55f395f51611080511815612f6d576015611720527f696e76616c6964207061796d656e7420746f6b656e00000000000000000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b611040516110c0511115612fe057601c611720527f6f726967696e6174696f6e20666565206774207072696e636970616c000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b610d2051426110a051808201828110615a935790509050101561306257601d611720527f6d61747572697479206265666f7265206c6f616e206d617475726974790000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b6020615b355f395f516356108f8a611760526111c051611780526040611760602461177c5f855af1613096573d5f5f3e3d5ffd5b60403d10615a9357611760518060a01c615a93576117c052611780516117e0526117c0905080516117205260208101516117405250610260604061026061104060045afa50610dc0516102a052611720516102c052611740516102e0526113005160208160051b01806103008261130060045afa505050613115613e1f565b610da05161172051181561318857601c611760527f636f6c6c61746572616c20636f6e7472616374206d69736d61746368000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b6102c06103a06102c061104060045afa506131a1614636565b610ca0516040526131b06154f5565b611040518060ff1c615a9357610cc0518060ff1c615a93578082038281135f831218615a935790509050611760526103e060406103e0610c6060045afa506131f96117a0615370565b6117a051611780526040366117a0375f611960526103e060406103e0610c6060045afa5061178051610420526132306119806153da565b611980805160206060820201806117c0828560045afa5050506101a08101516117a0526101c08101516119605250610260604061026061104060045afa506060366102a037613280611ba0614104565b611ba0805160208160071b0180611980828560045afa505050505f611ba0525f6119805160048111615a9357801561330357905b8060071b6119a0018051611bc0526020810151611be0526040810151611c00526060810151611c205250611ba051611be051808201828110615a935790509050611ba0526001018181186132b4575b50505f6002610c60516020525f5260405f20556103e060406103e0610c6060045afa5061026061042061026061104060045afa506117805161068052611960516106a052613352611be06158ea565b611be051611bc052611bc0518060ff1c615a93576117805161196051808201828110615a9357905090508060ff1c615a9357611760518082038281135f831218615a935790509050808281188284130218905090505f8112615a9357611be05261176051611780518060ff1c615a93578082038281135f831218615a935790509050611960518060ff1c615a93578082038281135f831218615a935790509050611be0518060ff1c615a93578082018281125f831218615a935790509050611c0052610cc05161178051808201828110615a93579050905061196051808201828110615a9357905090506110e051808201828110615a9357905090508060ff1c615a9357611ba0516117a051808201828110615a935790509050611be051808201828110615a9357905090508060ff1c615a93578082038281135f831218615a935790509050611c2052611040516110c051808203828111615a9357905090506110e051808201828110615a935790509050611c40525f611c00511215613538576012611c60527f626f72726f7765722064656c7461203c20300000000000000000000000000000611c8052611c6050611c605180611c8001601f825f031636823750506308c379a0611c20526020611c4052601f19601f611c60510116604401611c3cfd5b61122051610d8051146135f7575f611c205112156135b5576010611c60527f6c656e6465722064656c7461203c203000000000000000000000000000000000611c8052611c6050611c605180611c8001601f825f031636823750506308c379a0611c20526020611c4052601f19601f611c60510116604401611c3cfd5b61122051604052611c40516060526135cb615517565b6001611c2051126136ec57610d8051604052611c20515f8112615a93576060526136ec6155d6566136ec565b611c2051611c40518060ff1c615a93578082038281135f831218615a935790509050611c60525f611c6051131561368d576010611c80527f6c656e6465722064656c7461203e203000000000000000000000000000000000611ca052611c8050611c805180611ca001601f825f031636823750506308c379a0611c40526020611c6052601f19601f611c80510116604401611c5cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c6051136136ec57610d8051604052611c6051805f03600160ff1b82141582825f03141615615a935790505f8112615a93576060526136ec615517565b6001611c00511261371457610d6051604052611c00515f8112615a93576060526137146155d6565b5f6117c05160048111615a9357801561376b57905b606081026117e0018051611c60526020810151611c80526040810151611ca05250611ca051604052611c80516060526137606155d6565b600101818118613729575b50505f6119805160048111615a935780156137ea57905b8060071b6119a0018051611c60526020810151611c80526040810151611ca0526060810151611cc052506002611c6051146137c257611c805115156137c4565b5f5b156137df57611cc051604052611c80516060526137df6155d6565b600101818118613782575b50506102c060406102c061104060045afa50613807611c8061452b565b611c8051611c60525f611c8052611c6051611ca05261128051611cc05261104051611ce05261106051611d005261108051611d2052426110a051808201828110615a935790509050611d405242611d6052610d6051611d805261122051611da05261172051611dc052610dc051611de0526119805160208160071b0180611e008261198060045afa505050611240516120205261102051612040526103e060406103e0611c8060045afa506138bd612060614574565b61206051611c80526002611c80516020525f5260405f20541561393f576013612060527f6c6f616e20616c726561647920657869737473000000000000000000000000006120805261206050612060518061208001601f825f031636823750506308c379a061202052602061204052601f19601f61206051011660440161203cfd5b6103e060406103e0611c8060045afa5061395a6120606147a6565b612060516002611c80516020525f5260405f20557f3104dd99ab576a709e2bea4bedb076e17210d16fdbc54a86b7db45e9f3be8284610260611c805161206052611ce05161208052611d00516120a052611d20516120c052611d40516120e052611d605161210052611dc05161212052611de05161214052611d805161216052611da05161218052806121a05280612060015f611e00518083528060071b5f8260048111615a93578015613a4a57905b8060071b60208701018160071b611e2001805182526020810151602083015260408101516040830152606081015160608301525050600101818118613a0a575b50508201602001915050905081019050612020516121c052610c60516121e052610cc051612200526117805161222052806122405280612060015f6117c051808352606081025f8260048111615a93578015613ad857905b606081026020870101606082026117e0018051825260208101516020830152604081015160408301525050600101818118613aa2575b50508201602001915050905081019050611be05161226052611c605161228052611280516122a052612060a16020611c80f3613d08565b638199abaf8118613d085734615a93576009336020525f5260405f2054613b8b5760146040527f6e6f2070656e64696e67207472616e736665727300000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6009336020525f5260405f20546040525f6009336020525f5260405f20556020615ad55f395f5163a9059cbb6060523360805260405160a052602060606044607c5f855af1613bdc573d5f5f3e3d5ffd5b60203d10615a93576060518060011c615a935760c05260c0905051613c5957601360e0527f6572726f722073656e64696e672066756e6473000000000000000000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b7fb533bf65f7139533fed34316e420b8cefd0c9fb1730ceaf49fa4d0cd42341dd93360605260405160805260406060a100613d08565b63150b7a028118613d085760a436103417615a93576004358060a01c615a93576040526024358060a01c615a9357606052606435600401610400813511615a93576020813501808260803750507f150b7a02000000000000000000000000000000000000000000000000000000006104a05260206104a0f35b5f5ffd5b610300515f610760525f6002610320527f1901000000000000000000000000000000000000000000000000000000000000610340526103208051602082018361068001815181525050808301925050506020615bd5610620397fb54af15efd4078a08fa64b2ca6923174f13b55e91014d675bcae943a355f4335610380526102606103a0610260604060045afa50610280610360526103608051602082012090506106405260406106005261060080516020820183610680018281848460045afa50505080830192505050806106605261066090508051602082012090506106e0526102a051610700526102c051610720526102e05161074052602061076060806106e060015afa506107605114815250565b6102c051613e8c57601a610720527f636f6c6c61746572616c206e6f742077686974656c69737465640000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd5b60016101405118613f0e576102a051610160511815614102576015610720527f746f6b656e206964206e6f7420696e206f6666657200000000000000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd614102565b6002610140511861400357610180516102a0511015613f8c576019610720527f746f6b656e69642062656c6f77206f666665722072616e6765000000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd5b6101a0516102a0511115614102576019610720527f746f6b656e69642061626f7665206f666665722072616e6765000000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd614102565b6102c051610760526101e051610780526102a0516107a052606061074052610740805160208201209050610720525f6103005160208111615a9357801561408d57905b8060051b610320015161074052610740515f5260205f20610720515f5260205f20186107805260206107605261076080516020820120905061072052600101818118614046575b5050610720516102e051181561410257600d610740527f70726f6f6620696e76616c6964000000000000000000000000000000000000006107605261074050610740518061076001601f825f031636823750506308c379a061070052602061072052601f19601f61074051011660440161071cfd5b565b5f6103005260c051156141825760405160c051111561418257601c610520527f6f726967696e6174696f6e20666565206774207072696e636970616c000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6101005115614192576001614198565b60e05115155b1561420a576101205161420a57601a610520527f62726f6b65722066656520776974686f757420616464726573730000000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6102a0511561421a576001614221565b6102c05115155b15614293576102e05161429357601a610520527f62726f6b65722066656520776974686f757420616464726573730000000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6020615b955f395f5161010051111561430b57601d610520527f6c656e6465722062726f6b6572206665652065786365656473206d61780000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6020615bb55f395f516102c051111561438357601f610520527f626f72726f7765722062726f6b6572206665652065786365656473206d6178006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b61271060055461010051808201828110615a935790509050111561440657601c610520527f736574746c656d656e742066656573206774207072696e636970616c000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6103005160038111615a93578060071b6103200160018152600454604051808202811583838304141715615a93579050905061271081049050602082015260055460408201526003546060820152506001810161030052506103005160038111615a93578060071b610320016002815260c05160208201525f6040820152610220516060820152506001810161030052506103005160038111615a93578060071b610320016004815260e0516020820152610100516040820152610120516060820152506001810161030052506103005160038111615a93578060071b61032001600881526102a05160208201526102c05160408201526102e0516060820152506001810161030052506103005160208160071b0180838261030060045afa50505050565b5f6102a0518161032001526020810190506102c0518161032001526020810190506102e05181610320015260208101905080610300526103009050805160208201209050815250565b5f610140518161044001526020810190506101605181610440015260208101905061012051816104400152602081019050610180518161044001526020810190506101a05181610440015260208101905080610420526104209050805160208201209050815250565b600160076040516020525f5260405f20557f08f7f4fedc8c9bd3165579676da5b715f2babe388ed555519fcae0e56c2e507d6040516103205261024051610340526101e0516103605261016051610380526080610320a1565b6102c060406102c06103a060045afa5061465161068061452b565b61068051610660526007610660516020525f5260405f2054156146d357600d610680527f6f66666572207265766f6b6564000000000000000000000000000000000000006106a0526106805061068051806106a001601f825f031636823750506308c379a061064052602061066052601f19601f61068051011660440161065cfd5b60066105e0516020525f5260405f2054610680526105c05161068051106147595760146106a0527f6f666665722066756c6c79207574696c697a65640000000000000000000000006106c0526106a0506106a051806106c001601f825f031636823750506308c379a061066052602061068052601f19601f6106a051011660440161067cfd5b6106805160018101818110615a9357905060066105e0516020525f5260405f205560016104a051186147a457610660516040526102c060606102c06103a060045afa506147a46145dd565b565b6020806104405280610440016101e060405182526060516020830152608051604083015260a051606083015260c051608083015260e05160a08301526101005160c08301526101205160e08301526101405161010083015261016051610120830152610180516101408301526101a051610160830152806101808301528082015f6101c0518083528060071b5f8260048111615a9357801561488457905b8060071b60208701018160071b6101e001805182526020810151602083015260408101516040830152606081015160608301525050600101818118614844575b505082016020019150509050810190506103e0516101a0830152610400516101c083015290508101905061042052610420805160208201209050815250565b604051635817816860805260605160a052602060806024609c845afa6148eb573d5f5f3e3d5ffd5b60203d10615a93576080518060a01c615a935760c05260c0905051815250565b6020615b155f395f5163088f11f3610140526080516101605260a0610140602461015c845afa61493d573d5f5f3e3d5ffd5b60a03d10615a9357610140518060011c615a9357610200526101605161022052610180518060a01c615a9357610240526101a051610260526101c0518060a01c615a9357610280526102009050805160a052602081015160c052604081015160e0526060810151610100526080810151610120525060a0516149bf575f6149f5565b60805160c051186149f357610100516149ed57610120516149e15760016149f5565b306101205118156149f5565b5f6149f5565b5f5b815250565b60605163088f11f3610140526080516101605260a0610140602461015c845afa614a26573d5f5f3e3d5ffd5b60a03d10615a9357610140518060011c615a9357610200526101605161022052610180518060a01c615a9357610240526101a051610260526101c0518060a01c615a9357610280526102009050805160a052602081015160c052604081015160e0526060810151610100526080810151610120525060a051614b07576017610140527f636f6c6c61746572616c206e6f7420666f722073616c650000000000000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b60805160c0511815614b7857601f610140527f636f6c6c61746572616c20776974682077726f6e672070756e6b496e646578006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b60405160e0511815614be957601e610140527f636f6c6c61746572616c206e6f77206f776e65642062792077616c6c657400006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b6101005115614c5757601c610140527f636f6c6c61746572616c206f66666572206973206e6f74207a65726f000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b61012051614c66576001614c6e565b306101205118155b614cd7576020610140527f636f6c6c61746572616c20627579696e67206e6f7420617574686f72697a65646101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b606051638264fe986101405260805161016052803b15615a93575f610140602461015c5f855af1614d0a573d5f5f3e3d5ffd5b50565b604051636352211e60805260605160a052602060806024609c845afa614d35573d5f5f3e3d5ffd5b60203d10615a93576080518060a01c615a935760c05260c0905051815250565b60605163e985e9c560a05260405160c0523060e052602060a0604460bc845afa614d81573d5f5f3e3d5ffd5b60203d10615a935760a0518060011c615a935761010052610100905051614df4573060605163081812fc61012052608051610140526020610120602461013c845afa614dcf573d5f5f3e3d5ffd5b60203d10615a9357610120518060a01c615a9357610160526101609050511815614df7565b60015b815250565b60605163b88d4fde60c052608060405160e05230610100526080516101205280610140525f60a05260a08160e0015f81528051806020830101601f825f03163682375050601f19601f825160200101169050905081015050803b15615a93575f60c060a460dc5f855af1614e72573d5f5f3e3d5ffd5b50565b6020615b155f395f5160405114815250565b6102a051614ef4576015610300527f6164647220697320746865207a65726f206164647200000000000000000000006103205261030050610300518061032001601f825f031636823750506308c379a06102c05260206102e052601f19601f6103005101166044016102dcfd5b6102c051614f6157601c610300527f636f6c6c6174206164647220697320746865207a65726f2061646472000000006103205261030050610300518061032001601f825f031636823750506308c379a06102c05260206102e052601f19601f6103005101166044016102dcfd5b6102c051604052614f73610300614e75565b610300516150b5576102a0516102c0516040526102e051606052614f98610300614d0d565b61030051181561500757601e610320527f636f6c6c61746572616c206e6f74206f776e65642062792077616c6c657400006103405261032050610320518061034001601f825f031636823750506308c379a06102e052602061030052601f19601f6103205101166044016102fcfd5b6102a0516040526102c0516060526102e051608052615027610300614d55565b61030051615094576018610320527f7472616e73666572206973206e6f7420617070726f76656400000000000000006103405261032050610320518061034001601f825f031636823750506308c379a06102e052602061030052601f19601f6103205101166044016102fcfd5b6102a0516040526102c0516060526102e0516080526151eb614dfc566151eb565b6102a0516102c0516040526102e0516060526150d26103206148c3565b61032051181561514157601e610340527f636f6c6c61746572616c206e6f74206f776e65642062792077616c6c657400006103605261034050610340518061036001601f825f031636823750506308c379a061030052602061032052601f19601f61034051011660440161031cfd5b6102a0516040526102c0516060526102e05160805261516161032061490b565b610320516151ce576018610340527f7472616e73666572206973206e6f7420617070726f76656400000000000000006103605261034050610340518061036001601f825f031636823750506308c379a061030052602061032052601f19601f61034051011660440161031cfd5b6102a0516040526102c0516060526102e0516080526151eb6149fa565b565b6020615ad55f395f516323b872dd60a05260405160c05260605160e05260805161010052602060a0606460bc5f855af1615229573d5f5f3e3d5ffd5b60203d10615a935760a0518060011c615a9357610120526101209050516152af576013610140527f7472616e7366657246726f6d206661696c6564000000000000000000000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b565b6020615af55f395f5163b18e2bbb60c05260405160e05260605161010052608051610120525f6101405260a05161016052602060c060a460dc5f855af16152fa573d5f5f3e3d5ffd5b60203d10615a935760c05050565b6103e060406103e061086060045afa50615323610c406147a6565b610c40516002610860516020525f5260405f205414815250565b604051331861534d57600161536b565b6008336020525f5260405f2054615364575f61536b565b3260405118155b815250565b6103e0516153875760c0518152506153d8566153d8565b60c0514261012051808203828111615a935790509050808202811583838304141715615a9357905090506101005161012051808203828111615a9357905090508015615a9357808204905090508152505b565b604036610440375f610600525f6101c05160048111615a935780156154c457905b8060071b6101e0018051610620526020810151610640526040810151610660526060810151610680525061066051156154b9576104205161066051808202811583838304141715615a935790509050612710810490506106a0526104605160038111615a935760608102610480016106205181526106a051602082015261068051604082015250600181016104605250610440516106a051808201828110615a93579050905061044052600861062051186154b9576106a051610600525b6001018181186153fb575b5050610460516020606082020180838261046060045afa505050610440516101a0820152610600516101c082015250565b60066040516020525f5260405f20805460018103818111615a93579050815550565b6020615ad55f395f516323b872dd60805260405160a0523060c05260605160e052602060806064609c5f855af1615550573d5f5f3e3d5ffd5b60203d10615a93576080518060011c615a9357610100526101009050516155d4576013610120527f7472616e7366657246726f6d206661696c6564000000000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b565b6040366080376020615ad55f395f515a63a9059cbb60e4526004604051610104526060516101245260400160e05260e050602061018060e0516101005f8686f1905090506080523d602081183d602010021861016052610160805160a052602081015160c0525060805161564b57600161565a565b60c05160a05160200360031b1c155b156156b7577f1c43b9761b3fba5321ca8212bfc231945f668ccc0c446f333999eea9ce8fda8160405160e05260605161010052604060e0a160096040516020525f5260405f208054606051808201828110615a9357905090508155505b565b3061010051604052610120516060526156d36101406148c3565b61014051181561574257601d610160527f636f6c6c61746572616c206e6f74206f776e6564206279207661756c740000006101805261016050610160518061018001601f825f031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b61010051638b72a2ec6101405260e051610160526101205161018052803b15615a93575f610140604461015c5f855af161577e573d5f5f3e3d5ffd5b50565b30610100516040526101205160605261579b610140614d0d565b61014051181561580a57601d610160527f636f6c6c61746572616c206e6f74206f776e6564206279207661756c740000006101805261016050610160518061018001601f825f031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6101005163b88d4fde610160526080306101805260e0516101a052610120516101c052806101e0525f6101405261014081610180015f81528051806020830101601f825f03163682375050601f19601f825160200101169050905081015050803b15615a93575f61016060a461017c5f855af1615889573d5f5f3e3d5ffd5b50565b6102405160405261589e610280614e75565b610280516158c9576102205160e052610240516101005261026051610120526158e8615781566158e8565b6102205160e052610240516101005261026051610120526158e86156b9565b565b5f6106c0525f6101c05160048111615a9357801561594d57905b8060071b6101e00180516106e0526020810151610700526040810151610720526060810151610740525060086106e0511861594257610720516106c0525b600101818118615904575b50506106205161595f57610440615968565b5f610700526107005b516106e0526106205161597b575f6159b0565b60c05161068051808203828111615a9357905090506106c051808202811583838304141715615a935790509050612710810490505b6107005260c05161068051808203828111615a93579050905061072052610620516159dd57610440615a21565b610440516101005142808203828111615a935790509050808202811583838304141715615a935790509050610480518015615a935780820490509050610760526107605b51610740526106e0518060ff1c615a9357610740518060ff1c615a9357610720518060ff1c615a93578082038281135f831218615a935790509050610700518060ff1c615a93578082038281135f831218615a935790509050808281188284130218905090505f8112615a9357815250565b5f80fd11e5075c08193c8f3d0807db2a873b0f09081c683d083d0800643d083d0817103d0801023d0811a608e805a0077e00183d080493092a3d081175115315e884195ad581183e190120a16576797065728300030a0017000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a11704b3dd545dc0771d9a9c5572064db2a5c06200000000000000000000000000000000000000447e69651d841bd8d104bed493000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007d96cc26566bfca358c61fbe7be3ca771da7ea60000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000013880000000000000000000000000000000000000000000000000000000000001388
Deployed Bytecode
0x5f3560e01c6002601f820660011b615a9701601e395f51565b638da5cb5b81186100335734615a93575f5460405260206040f35b6361acb5598118613d0857602436103417615a935760076004356020525f5260405f205460405260206040f3613d08565b63885753de81186100805734615a935760015460405260206040f35b63ffa1ad748118613d085734615a935760208060805260176040527f5032504c656e64696e674e6674732e323032343130303200000000000000000060605260408160800181518152602082015160208201528051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f3613d08565b63331c658781186101205734615a93576020615ad560403960206040f35b6305107f058118613d085761022436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a9357801561023e57905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a9357606083015250506001018181186101ee575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a935761102052506103e06108606103e0610c6060045afa50610288611040615308565b611040516102f557600c611060527f696e76616c6964206c6f616e00000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b610d20514211610364576012611040527f6c6f616e206e6f742064656661756c74656400000000000000000000000000006110605261104050611040518061106001601f825f031636823750506308c379a061100052602061102052601f19601f61104051011660440161101cfd5b610d805160405261037661104061533d565b611040516103e357600a611060527f6e6f74206c656e646572000000000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b5f6002610c60516020525f5260405f2055610d805161022052610da05161024052610dc0516102605261041461588c565b611020511561043e5761102051604052610da051606052610dc0516080525f60a05261043e6152b1565b7f4a55c2facef4f87dd498aace39997457e1fc66968956bfe3ac7f20f736e77e74610c605161104052610d605161106052610d805161108052610da0516110a052610dc0516110c05260a0611040a100613d08565b63c4a9081581186104c057602436103417615a935760026004356020525f5260405f205460405260206040f35b639544fa7c8118613d0857604436103417615a93576004358060a01c615a93576040526024358060011c615a93576060525f543318156105565760096080527f6e6f74206f776e6572000000000000000000000000000000000000000000000060a0526080506080518060a001601f825f031636823750506308c379a06040526020606052601f19601f6080510116604401605cfd5b60605160086040516020525f5260405f20557f5e09e79221e29a6d762b708b6fa399e730dfc027f946b2e81a31d849b2fb1fa960405160805260605160a05260406080a100613d08565b63e5107ed781186105be5734615a93576020615af560403960206040f35b63c2a5022b8118613d0857604436103417615a93575f543318156106375760096040527f6e6f74206f776e6572000000000000000000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6020615b555f395f5160043511156106a45760176040527f757066726f6e74206665652065786365656473206d617800000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6020615b755f395f51602435111561071157601a6040527f736574746c656d656e74206665652065786365656473206d617800000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b7f4bfb2e8697c06dccd3777bdd9b4dab854905ca53b2a56bb47882c744729729d46004546040526005546060526040600460803760806040a160043560045560243560055500613d08565b635556eda98118613d085734615a93576020615b1560403960206040f3613d08565b637719e9ea811861079c5734615a93576020615b3560403960206040f35b639274bbcd8118613d0857602436103417615a93576004358060a01c615a935760405260096040516020525f5260405f205460605260206060f3613d08565b6367db749981186107f75734615a935760035460405260206040f35b63f8c266298118613d085734615a93576020615b9560403960206040f3613d08565b6358e7783781186108355734615a935760045460405260206040f35b63f7a79a028118613d085734615a93576001543318156108aa5760166040527f6e6f74207468652070726f706f736564206f776e65720000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f5460405260015460605260406040a1335f555f60015500613d08565b6361dd0b8b8118613d085734615a935760055460405260206040f3613d08565b6350d0d5ad8118613d085734615a93576020615b5560403960206040f3613d08565b6387c8f69481186109485734615a93576020615b7560403960206040f35b63a1c7a5678118613d08576103a436103417615a935760406004610860376044358060a01c615a93576108a0526064356108c052606060846108e03760e4358060a01c615a935761094052610104358060031c615a935761096052610124356109805260a06101446109a0376101e4358060a01c615a9357610a4052610204358060011c615a9357610a60526040610224610a80376060610264610ac0376102e4356004016020813511615a9357803560208160051b018083610b2037505050610304358060a01c615a9357610f4052610364358060a01c615a9357610f60526102c060406102c061086060045afa50610a405161030052610a4b610f80613d0c565b610f8051610ab857601a610fa0527f6f66666572206e6f74207369676e6564206279206c656e646572000000000000610fc052610fa050610fa05180610fc001601f825f031636823750506308c379a0610f60526020610f8052601f19601f610fa0510116604401610f7cfd5b42610a205111610b2757600d610f80527f6f66666572206578706972656400000000000000000000000000000000000000610fa052610f8050610f805180610fa001601f825f031636823750506308c379a0610f40526020610f6052601f19601f610f80510116604401610f5cfd5b6020615ad55f395f516108a0511815610b9f576015610f80527f696e76616c6964207061796d656e7420746f6b656e0000000000000000000000610fa052610f8050610f805180610fa001601f825f031636823750506308c379a0610f40526020610f6052601f19601f610f80510116604401610f5cfd5b610860516108e0511115610c1257601c610f80527f6f726967696e6174696f6e20666565206774207072696e636970616c00000000610fa052610f8050610f805180610fa001601f825f031636823750506308c379a0610f40526020610f6052601f19601f610f80510116604401610f5cfd5b6020615b355f395f516356108f8a610fc0526109e051610fe0526040610fc06024610fdc5f855af1610c46573d5f5f3e3d5ffd5b60403d10615a9357610fc0518060a01c615a935761102052610fe0516110405261102090508051610f80526020810151610fa05250610260604061026061086060045afa506102c4356102a052610f80516102c052610fa0516102e052610b205160208160051b018061030082610b2060045afa505050610cc5613e1f565b610260604061026061086060045afa5060406103246102a037610f60516102e052610cf16111e0614104565b6111e0805160208160071b0180610fc0828560045afa505050505f6111e0525f610fc05160048111615a93578015610d7457905b8060071b610fe001805161120052602081015161122052604081015161124052606081015161126052506111e05161122051808201828110615a9357905090506111e052600101818118610d25575b50506102c060406102c061086060045afa50610d9161122061452b565b61122051611200525f611220526112005161124052610aa051611260526108605161128052610880516112a0526108a0516112c052426108c051808201828110615a9357905090506112e05242611300526008336020525f5260405f2054610df95733610dfb565b325b61132052610a405161134052610f8051611360526102c43561138052610fc05160208160071b01806113a082610fc060045afa505050610a60516115c052610f40516115e0526103e060406103e061122060045afa50610e5c611600614574565b61160051611220526002611220516020525f5260405f205415610ede576013611600527f6c6f616e20616c726561647920657869737473000000000000000000000000006116205261160050611600518061162001601f825f031636823750506308c379a06115c05260206115e052601f19601f6116005101166044016115dcfd5b6102c06103a06102c061086060045afa50610ef7614636565b6103e060406103e061122060045afa50610f126116006147a6565b611600516002611220516020525f5260405f2055611320516102a052611360516102c052611380516102e052610f46614e87565b6113405160405261132051606052611280516111e051808203828111615a93579050905061090051808201828110615a935790509050608052610f876151ed565b5f610fc05160048111615a9357801561100b57905b8060071b610fe0018051611600526020810151611620526040810151611640526060810151611660525060026116005114610fdc57611620511515610fde565b5f5b15611000576113405160405261166051606052611620516080526110006151ed565b600101818118610f9c575b5050610f40511561103857610f40516040526113605160605261138051608052600160a0526110386152b1565b7f6827a33d0a24e36314681156d8d9a7d20d6a0548c169735fe25e00c9d38ac5a96101e0611220516116005261128051611620526112a051611640526112c051611660526112e05161168052611300516116a052611320516116c052611340516116e05261136051611700526113805161172052806117405280611600015f6113a0518083528060071b5f8260048111615a9357801561111457905b8060071b60208701018160071b6113c0018051825260208101516020830152604081015160408301526060810151606083015250506001018181186110d4575b505082016020019150509050810190506115c051611760526112005161178052610aa0516117a052610f40516117c052611600a16020611220f3613d08565b631b0b0c638118613d085734615a93576020615bb560403960206040f3613d08565b63225daa0f8118613d0857602436103417615a935760066004356020525f5260405f205460405260206040f3613d08565b6396069a5f8118613d0857602436103417615a93576004358060a01c615a935760405260086040516020525f5260405f205460605260206060f3613d08565b6372e76f13811861130a57602436103417615a93576004358060a01c615a93576040525f5433181561126d5760096060527f6e6f74206f776e6572000000000000000000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516112d057601a6060527f77616c6c657420697320746865207a65726f206164647265737300000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b7f6defa6e1a7dcc97f459fb552cf25427ab19cd60692b94e4f38660850a6e917e860035460605260405160805260406060a1604051600355005b63c75b6e5e8118613d08576102c436103417615a935760406004610780376044358060a01c615a93576107c0526064356107e052606060846108003760e4358060a01c615a935761086052610104358060031c615a935761088052610124356108a05260a06101446108c0376101e4358060a01c615a935761096052610204358060011c615a93576109805260406102246109a03760606102646109e037610960516040526113ba610a4061533d565b610a405161142757600a610a60527f6e6f74206c656e64657200000000000000000000000000000000000000000000610a8052610a6050610a605180610a8001601f825f031636823750506308c379a0610a20526020610a4052601f19601f610a60510116604401610a3cfd5b42610940511161149657600d610a40527f6f66666572206578706972656400000000000000000000000000000000000000610a6052610a4050610a405180610a6001601f825f031636823750506308c379a0610a00526020610a2052601f19601f610a40510116604401610a1cfd5b6102c060406102c061078060045afa5061096051610300526114b9610a40613d0c565b610a405161152657601a610a60527f6f66666572206e6f74207369676e6564206279206c656e646572000000000000610a8052610a6050610a605180610a8001601f825f031636823750506308c379a0610a20526020610a4052601f19601f610a60510116604401610a3cfd5b6102c060406102c061078060045afa50611541610a6061452b565b610a6051610a40526007610a40516020525f5260405f2054156115c3576015610a60527f6f6666657220616c7265616479207265766f6b65640000000000000000000000610a8052610a6050610a605180610a8001601f825f031636823750506308c379a0610a20526020610a4052601f19601f610a60510116604401610a3cfd5b610a40516040526102c060606102c061078060045afa506115e26145dd565b00613d08565b63bc71771d8118613d0857602436103417615a93576004358060a01c615a93576040525f543318156116705760096060527f6e6f74206f776e6572000000000000000000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6040516116d35760106060527f5f61646472657373206973207a65726f0000000000000000000000000000000060805260605060605180608001601f825f031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b7f722cace8a9cbcb7713f3f71015c8c6b59ed317672489140eb6b3fa7f4a139d845f5460605260405160805260406060a160405160015500613d08565b63802d67998118613d085761022436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a9357801561182e57905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a9357606083015250506001018181186117de575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a935761102052506103e06108606103e0610c6060045afa50611878611040615308565b611040516118e557600c611060527f696e76616c6964206c6f616e00000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b610d205142111561195557600e611040527f6c6f616e2064656661756c7465640000000000000000000000000000000000006110605261104050611040518061106001601f825f031636823750506308c379a061100052602061102052601f19601f61104051011660440161101cfd5b610d605160405261196761104061533d565b611040516119d457600c611060527f6e6f7420626f72726f77657200000000000000000000000000000000000000006110805261106050611060518061108001601f825f031636823750506308c379a061102052602061104052601f19601f61106051011660440161103cfd5b6103e060406103e0610c6060045afa506119ef611060615370565b6110605161104052604036611060375f611220526103e060406103e0610c6060045afa506110405161042052611a266112406153da565b61124080516020606082020180611080828560045afa5050506101a0810151611060526101c081015161122052505f6002610c60516020525f5260405f2055610ca051604052611a746154f5565b610d6051604052610cc05161104051808201828110615a93579050905061122051808201828110615a935790509050606052611aae615517565b610d8051604052610cc05161104051808201828110615a93579050905061106051808203828111615a93579050905061122051808201828110615a935790509050606052611afa6155d6565b5f6110805160048111615a93578015611b5157905b606081026110a001805161124052602081015161126052604081015161128052506112805160405261126051606052611b466155d6565b600101818118611b0f575b5050610d605161022052610da05161024052610dc05161026052611b7361588c565b6110205115611b9d5761102051604052610da051606052610dc0516080525f60a052611b9d6152b1565b7f2aa6f229bb00348f1aa98ab5ab1636a2618696536f698200d76b66a87906eafa60e0610c605161124052610d605161126052610d805161128052610d00516112a052610cc0516112c052611040516112e052806113005280611240015f61108051808352606081025f8260048111615a93578015611c4e57905b606081026020870101606082026110a0018051825260208101516020830152604081015160408301525050600101818118611c18575b50508201602001915050905081019050611240a100613d08565b6313c072ee8118613d085761058436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a93578015611d8657905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a935760608301525050600101818118611d36575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a9357611020525060406024611040376064358060a01c615a9357611080526084356110a052606060a46110c037610104358060a01c615a935761112052610124358060031c615a935761114052610144356111605260a061016461118037610204358060a01c615a935761122052610224358060011c615a93576112405260406102446112603760606102846112a0376102e4356004016020813511615a9357803560208160051b01808361130037505050610344358060a01c615a9357611720526103e06108606103e0610c6060045afa50611e8b611740615308565b61174051611ef857600c611760527f696e76616c6964206c6f616e00000000000000000000000000000000000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b610d6051604052611f0a61174061533d565b61174051611f7757600c611760527f6e6f7420626f72726f77657200000000000000000000000000000000000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b610d2051421115611fe757600e611740527f6c6f616e2064656661756c7465640000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b6102c060406102c061104060045afa50611220516103005261200a611740613d0c565b6117405161207757601a611760527f6f66666572206e6f74207369676e6564206279206c656e6465720000000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b4261120051116120e657600d611740527f6f666665722065787069726564000000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b6020615ad55f395f5161108051181561215e576015611740527f696e76616c6964207061796d656e7420746f6b656e00000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b611040516110c05111156121d157601c611740527f6f726967696e6174696f6e20666565206774207072696e636970616c000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b6020615b355f395f516356108f8a611780526111c0516117a0526040611780602461179c5f855af1612205573d5f5f3e3d5ffd5b60403d10615a9357611780518060a01c615a93576117e0526117a051611800526117e0905080516117405260208101516117605250610260604061026061104060045afa50610dc0516102a052611740516102c052611760516102e0526113005160208160051b01806103008261130060045afa505050612284613e1f565b610da0516117405118156122f757601c611780527f636f6c6c61746572616c20636f6e7472616374206d69736d61746368000000006117a0526117805061178051806117a001601f825f031636823750506308c379a061174052602061176052601f19601f61178051011660440161175cfd5b6102c06103a06102c061104060045afa50612310614636565b610ca05160405261231f6154f5565b611040518060ff1c615a9357610cc0518060ff1c615a93578082038281135f831218615a935790509050611780526103e060406103e0610c6060045afa506123686117c0615370565b6117c0516117a0526040366117c0375f611980526103e060406103e0610c6060045afa506117a0516104205261239f6119a06153da565b6119a0805160206060820201806117e0828560045afa5050506101a08101516117c0526101c08101516119805250610260604061026061104060045afa5060406103046102a037611720516102e0526123f9611bc0614104565b611bc0805160208160071b01806119a0828560045afa505050505f611bc0525f6119a05160048111615a9357801561247c57905b8060071b6119c0018051611be0526020810151611c00526040810151611c20526060810151611c405250611bc051611c0051808201828110615a935790509050611bc05260010181811861242d575b50505f6002610c60516020525f5260405f205561178051611bc0516117a051808201828110615a93579050905061198051808201828110615a9357905090508060ff1c615a93578082038281135f831218615a9357905090506110e0518060ff1c615a93578082018281125f831218615a935790509050611be052610cc0516117a051808201828110615a9357905090506117c051808203828111615a93579050905061198051808201828110615a935790509050611c0052611040516110c051808203828111615a9357905090506110e051808201828110615a935790509050611c20527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611be051136125c057610d6051604052611be051805f03600160ff1b82141582825f03141615615a935790505f8112615a93576060526125c0615517565b61122051610d8051146125fd5761122051604052611c20516060526125e3615517565b610d8051604052611c005160605261266c6155d65661266c565b611c2051611c00511161264457611c2051611c0051101561266c57610d8051604052611c2051611c0051808203828111615a93579050905060605261266c6155175661266c565b610d8051604052611c0051611c2051808203828111615a93579050905060605261266c6155d6565b6001611be0511261269457610d6051604052611be0515f8112615a93576060526126946155d6565b5f6117e05160048111615a935780156126eb57905b60608102611800018051611c40526020810151611c60526040810151611c805250611c8051604052611c60516060526126e06155d6565b6001018181186126a9575b50505f6119a05160048111615a9357801561276a57905b8060071b6119c0018051611c40526020810151611c60526040810151611c80526060810151611ca052506002611c40511461274257611c60511515612744565b5f5b1561275f57611ca051604052611c605160605261275f6155d6565b600101818118612702575b50506102c060406102c061104060045afa50612787611c6061452b565b611c6051611c40525f611c6052611c4051611c805261128051611ca05261104051611cc05261106051611ce05261108051611d0052426110a051808201828110615a935790509050611d205242611d4052610d6051611d605261122051611d805261174051611da052610dc051611dc0526119a05160208160071b0180611de0826119a060045afa505050611240516120005261102051612020526103e060406103e0611c6060045afa5061283d612040614574565b61204051611c60526002611c60516020525f5260405f2054156128bf576013612040527f6c6f616e20616c726561647920657869737473000000000000000000000000006120605261204050612040518061206001601f825f031636823750506308c379a061200052602061202052601f19601f61204051011660440161201cfd5b6103e060406103e0611c6060045afa506128da6120406147a6565b612040516002611c60516020525f5260405f20557fadf0e5d2eb7098352961e41ff94c8d5bd1e0d24910d7c8e7ae147610146fef21610240611c605161204052611cc05161206052611ce05161208052611d00516120a052611d20516120c052611d40516120e052611da05161210052611dc05161212052611d605161214052611d805161216052806121805280612040015f611de0518083528060071b5f8260048111615a935780156129ca57905b8060071b60208701018160071b611e000180518252602081015160208301526040810151604083015260608101516060830152505060010181811861298a575b50508201602001915050905081019050612000516121a052610c60516121c052610cc0516121e0526117a05161220052806122205280612040015f6117e051808352606081025f8260048111615a93578015612a5857905b60608102602087010160608202611800018051825260208101516020830152604081015160408301525050600101818118612a22575b50508201602001915050905081019050611c4051612240526112805161226052612040a16020611c60f3613d08565b63304b74ed8118613d085761052436103417615a93576004356004018035610c60526020810135610c80526040810135610ca0526060810135610cc0526080810135610ce05260a08101358060a01c615a9357610d005260c0810135610d205260e0810135610d40526101008101358060a01c615a9357610d60526101208101358060a01c615a9357610d80526101408101358060a01c615a9357610da052610160810135610dc05261018081013581016004813511615a935780355f8160048111615a93578015612ba557905b8060071b610e00018160071b602086010180358060041c615a93578252602081013560208301526040810135604083015260608101358060a01c615a935760608301525050600101818118612b55575b505080610de05250506101a08101358060011c615a9357611000526101c08101358060a01c615a9357611020525060406024611040376064358060a01c615a9357611080526084356110a052606060a46110c037610104358060a01c615a935761112052610124358060031c615a935761114052610144356111605260a061016461118037610204358060a01c615a935761122052610224358060011c615a93576112405260406102446112603760606102846112a0376102e4356004016020813511615a9357803560208160051b018083611300375050506103e06108606103e0610c6060045afa50612c9a611720615308565b61172051612d0757600c611740527f696e76616c6964206c6f616e00000000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b610d8051604052612d1961172061533d565b61172051612d8657600a611740527f6e6f74206c656e646572000000000000000000000000000000000000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b610d2051421115612df657600e611720527f6c6f616e2064656661756c7465640000000000000000000000000000000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b6102c060406102c061104060045afa506112205161030052612e19611720613d0c565b61172051612e8657601a611740527f6f66666572206e6f74207369676e6564206279206c656e6465720000000000006117605261174050611740518061176001601f825f031636823750506308c379a061170052602061172052601f19601f61174051011660440161171cfd5b426112005111612ef557600d611720527f6f666665722065787069726564000000000000000000000000000000000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b6020615ad55f395f51611080511815612f6d576015611720527f696e76616c6964207061796d656e7420746f6b656e00000000000000000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b611040516110c0511115612fe057601c611720527f6f726967696e6174696f6e20666565206774207072696e636970616c000000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b610d2051426110a051808201828110615a935790509050101561306257601d611720527f6d61747572697479206265666f7265206c6f616e206d617475726974790000006117405261172050611720518061174001601f825f031636823750506308c379a06116e052602061170052601f19601f6117205101166044016116fcfd5b6020615b355f395f516356108f8a611760526111c051611780526040611760602461177c5f855af1613096573d5f5f3e3d5ffd5b60403d10615a9357611760518060a01c615a93576117c052611780516117e0526117c0905080516117205260208101516117405250610260604061026061104060045afa50610dc0516102a052611720516102c052611740516102e0526113005160208160051b01806103008261130060045afa505050613115613e1f565b610da05161172051181561318857601c611760527f636f6c6c61746572616c20636f6e7472616374206d69736d61746368000000006117805261176050611760518061178001601f825f031636823750506308c379a061172052602061174052601f19601f61176051011660440161173cfd5b6102c06103a06102c061104060045afa506131a1614636565b610ca0516040526131b06154f5565b611040518060ff1c615a9357610cc0518060ff1c615a93578082038281135f831218615a935790509050611760526103e060406103e0610c6060045afa506131f96117a0615370565b6117a051611780526040366117a0375f611960526103e060406103e0610c6060045afa5061178051610420526132306119806153da565b611980805160206060820201806117c0828560045afa5050506101a08101516117a0526101c08101516119605250610260604061026061104060045afa506060366102a037613280611ba0614104565b611ba0805160208160071b0180611980828560045afa505050505f611ba0525f6119805160048111615a9357801561330357905b8060071b6119a0018051611bc0526020810151611be0526040810151611c00526060810151611c205250611ba051611be051808201828110615a935790509050611ba0526001018181186132b4575b50505f6002610c60516020525f5260405f20556103e060406103e0610c6060045afa5061026061042061026061104060045afa506117805161068052611960516106a052613352611be06158ea565b611be051611bc052611bc0518060ff1c615a93576117805161196051808201828110615a9357905090508060ff1c615a9357611760518082038281135f831218615a935790509050808281188284130218905090505f8112615a9357611be05261176051611780518060ff1c615a93578082038281135f831218615a935790509050611960518060ff1c615a93578082038281135f831218615a935790509050611be0518060ff1c615a93578082018281125f831218615a935790509050611c0052610cc05161178051808201828110615a93579050905061196051808201828110615a9357905090506110e051808201828110615a9357905090508060ff1c615a9357611ba0516117a051808201828110615a935790509050611be051808201828110615a9357905090508060ff1c615a93578082038281135f831218615a935790509050611c2052611040516110c051808203828111615a9357905090506110e051808201828110615a935790509050611c40525f611c00511215613538576012611c60527f626f72726f7765722064656c7461203c20300000000000000000000000000000611c8052611c6050611c605180611c8001601f825f031636823750506308c379a0611c20526020611c4052601f19601f611c60510116604401611c3cfd5b61122051610d8051146135f7575f611c205112156135b5576010611c60527f6c656e6465722064656c7461203c203000000000000000000000000000000000611c8052611c6050611c605180611c8001601f825f031636823750506308c379a0611c20526020611c4052601f19601f611c60510116604401611c3cfd5b61122051604052611c40516060526135cb615517565b6001611c2051126136ec57610d8051604052611c20515f8112615a93576060526136ec6155d6566136ec565b611c2051611c40518060ff1c615a93578082038281135f831218615a935790509050611c60525f611c6051131561368d576010611c80527f6c656e6465722064656c7461203e203000000000000000000000000000000000611ca052611c8050611c805180611ca001601f825f031636823750506308c379a0611c40526020611c6052601f19601f611c80510116604401611c5cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611c6051136136ec57610d8051604052611c6051805f03600160ff1b82141582825f03141615615a935790505f8112615a93576060526136ec615517565b6001611c00511261371457610d6051604052611c00515f8112615a93576060526137146155d6565b5f6117c05160048111615a9357801561376b57905b606081026117e0018051611c60526020810151611c80526040810151611ca05250611ca051604052611c80516060526137606155d6565b600101818118613729575b50505f6119805160048111615a935780156137ea57905b8060071b6119a0018051611c60526020810151611c80526040810151611ca0526060810151611cc052506002611c6051146137c257611c805115156137c4565b5f5b156137df57611cc051604052611c80516060526137df6155d6565b600101818118613782575b50506102c060406102c061104060045afa50613807611c8061452b565b611c8051611c60525f611c8052611c6051611ca05261128051611cc05261104051611ce05261106051611d005261108051611d2052426110a051808201828110615a935790509050611d405242611d6052610d6051611d805261122051611da05261172051611dc052610dc051611de0526119805160208160071b0180611e008261198060045afa505050611240516120205261102051612040526103e060406103e0611c8060045afa506138bd612060614574565b61206051611c80526002611c80516020525f5260405f20541561393f576013612060527f6c6f616e20616c726561647920657869737473000000000000000000000000006120805261206050612060518061208001601f825f031636823750506308c379a061202052602061204052601f19601f61206051011660440161203cfd5b6103e060406103e0611c8060045afa5061395a6120606147a6565b612060516002611c80516020525f5260405f20557f3104dd99ab576a709e2bea4bedb076e17210d16fdbc54a86b7db45e9f3be8284610260611c805161206052611ce05161208052611d00516120a052611d20516120c052611d40516120e052611d605161210052611dc05161212052611de05161214052611d805161216052611da05161218052806121a05280612060015f611e00518083528060071b5f8260048111615a93578015613a4a57905b8060071b60208701018160071b611e2001805182526020810151602083015260408101516040830152606081015160608301525050600101818118613a0a575b50508201602001915050905081019050612020516121c052610c60516121e052610cc051612200526117805161222052806122405280612060015f6117c051808352606081025f8260048111615a93578015613ad857905b606081026020870101606082026117e0018051825260208101516020830152604081015160408301525050600101818118613aa2575b50508201602001915050905081019050611be05161226052611c605161228052611280516122a052612060a16020611c80f3613d08565b638199abaf8118613d085734615a93576009336020525f5260405f2054613b8b5760146040527f6e6f2070656e64696e67207472616e736665727300000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b6009336020525f5260405f20546040525f6009336020525f5260405f20556020615ad55f395f5163a9059cbb6060523360805260405160a052602060606044607c5f855af1613bdc573d5f5f3e3d5ffd5b60203d10615a93576060518060011c615a935760c05260c0905051613c5957601360e0527f6572726f722073656e64696e672066756e6473000000000000000000000000006101005260e05060e0518061010001601f825f031636823750506308c379a060a052602060c052601f19601f60e051011660440160bcfd5b7fb533bf65f7139533fed34316e420b8cefd0c9fb1730ceaf49fa4d0cd42341dd93360605260405160805260406060a100613d08565b63150b7a028118613d085760a436103417615a93576004358060a01c615a93576040526024358060a01c615a9357606052606435600401610400813511615a93576020813501808260803750507f150b7a02000000000000000000000000000000000000000000000000000000006104a05260206104a0f35b5f5ffd5b610300515f610760525f6002610320527f1901000000000000000000000000000000000000000000000000000000000000610340526103208051602082018361068001815181525050808301925050506020615bd5610620397fb54af15efd4078a08fa64b2ca6923174f13b55e91014d675bcae943a355f4335610380526102606103a0610260604060045afa50610280610360526103608051602082012090506106405260406106005261060080516020820183610680018281848460045afa50505080830192505050806106605261066090508051602082012090506106e0526102a051610700526102c051610720526102e05161074052602061076060806106e060015afa506107605114815250565b6102c051613e8c57601a610720527f636f6c6c61746572616c206e6f742077686974656c69737465640000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd5b60016101405118613f0e576102a051610160511815614102576015610720527f746f6b656e206964206e6f7420696e206f6666657200000000000000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd614102565b6002610140511861400357610180516102a0511015613f8c576019610720527f746f6b656e69642062656c6f77206f666665722072616e6765000000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd5b6101a0516102a0511115614102576019610720527f746f6b656e69642061626f7665206f666665722072616e6765000000000000006107405261072050610720518061074001601f825f031636823750506308c379a06106e052602061070052601f19601f6107205101166044016106fcfd614102565b6102c051610760526101e051610780526102a0516107a052606061074052610740805160208201209050610720525f6103005160208111615a9357801561408d57905b8060051b610320015161074052610740515f5260205f20610720515f5260205f20186107805260206107605261076080516020820120905061072052600101818118614046575b5050610720516102e051181561410257600d610740527f70726f6f6620696e76616c6964000000000000000000000000000000000000006107605261074050610740518061076001601f825f031636823750506308c379a061070052602061072052601f19601f61074051011660440161071cfd5b565b5f6103005260c051156141825760405160c051111561418257601c610520527f6f726967696e6174696f6e20666565206774207072696e636970616c000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6101005115614192576001614198565b60e05115155b1561420a576101205161420a57601a610520527f62726f6b65722066656520776974686f757420616464726573730000000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6102a0511561421a576001614221565b6102c05115155b15614293576102e05161429357601a610520527f62726f6b65722066656520776974686f757420616464726573730000000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6020615b955f395f5161010051111561430b57601d610520527f6c656e6465722062726f6b6572206665652065786365656473206d61780000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6020615bb55f395f516102c051111561438357601f610520527f626f72726f7765722062726f6b6572206665652065786365656473206d6178006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b61271060055461010051808201828110615a935790509050111561440657601c610520527f736574746c656d656e742066656573206774207072696e636970616c000000006105405261052050610520518061054001601f825f031636823750506308c379a06104e052602061050052601f19601f6105205101166044016104fcfd5b6103005160038111615a93578060071b6103200160018152600454604051808202811583838304141715615a93579050905061271081049050602082015260055460408201526003546060820152506001810161030052506103005160038111615a93578060071b610320016002815260c05160208201525f6040820152610220516060820152506001810161030052506103005160038111615a93578060071b610320016004815260e0516020820152610100516040820152610120516060820152506001810161030052506103005160038111615a93578060071b61032001600881526102a05160208201526102c05160408201526102e0516060820152506001810161030052506103005160208160071b0180838261030060045afa50505050565b5f6102a0518161032001526020810190506102c0518161032001526020810190506102e05181610320015260208101905080610300526103009050805160208201209050815250565b5f610140518161044001526020810190506101605181610440015260208101905061012051816104400152602081019050610180518161044001526020810190506101a05181610440015260208101905080610420526104209050805160208201209050815250565b600160076040516020525f5260405f20557f08f7f4fedc8c9bd3165579676da5b715f2babe388ed555519fcae0e56c2e507d6040516103205261024051610340526101e0516103605261016051610380526080610320a1565b6102c060406102c06103a060045afa5061465161068061452b565b61068051610660526007610660516020525f5260405f2054156146d357600d610680527f6f66666572207265766f6b6564000000000000000000000000000000000000006106a0526106805061068051806106a001601f825f031636823750506308c379a061064052602061066052601f19601f61068051011660440161065cfd5b60066105e0516020525f5260405f2054610680526105c05161068051106147595760146106a0527f6f666665722066756c6c79207574696c697a65640000000000000000000000006106c0526106a0506106a051806106c001601f825f031636823750506308c379a061066052602061068052601f19601f6106a051011660440161067cfd5b6106805160018101818110615a9357905060066105e0516020525f5260405f205560016104a051186147a457610660516040526102c060606102c06103a060045afa506147a46145dd565b565b6020806104405280610440016101e060405182526060516020830152608051604083015260a051606083015260c051608083015260e05160a08301526101005160c08301526101205160e08301526101405161010083015261016051610120830152610180516101408301526101a051610160830152806101808301528082015f6101c0518083528060071b5f8260048111615a9357801561488457905b8060071b60208701018160071b6101e001805182526020810151602083015260408101516040830152606081015160608301525050600101818118614844575b505082016020019150509050810190506103e0516101a0830152610400516101c083015290508101905061042052610420805160208201209050815250565b604051635817816860805260605160a052602060806024609c845afa6148eb573d5f5f3e3d5ffd5b60203d10615a93576080518060a01c615a935760c05260c0905051815250565b6020615b155f395f5163088f11f3610140526080516101605260a0610140602461015c845afa61493d573d5f5f3e3d5ffd5b60a03d10615a9357610140518060011c615a9357610200526101605161022052610180518060a01c615a9357610240526101a051610260526101c0518060a01c615a9357610280526102009050805160a052602081015160c052604081015160e0526060810151610100526080810151610120525060a0516149bf575f6149f5565b60805160c051186149f357610100516149ed57610120516149e15760016149f5565b306101205118156149f5565b5f6149f5565b5f5b815250565b60605163088f11f3610140526080516101605260a0610140602461015c845afa614a26573d5f5f3e3d5ffd5b60a03d10615a9357610140518060011c615a9357610200526101605161022052610180518060a01c615a9357610240526101a051610260526101c0518060a01c615a9357610280526102009050805160a052602081015160c052604081015160e0526060810151610100526080810151610120525060a051614b07576017610140527f636f6c6c61746572616c206e6f7420666f722073616c650000000000000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b60805160c0511815614b7857601f610140527f636f6c6c61746572616c20776974682077726f6e672070756e6b496e646578006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b60405160e0511815614be957601e610140527f636f6c6c61746572616c206e6f77206f776e65642062792077616c6c657400006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b6101005115614c5757601c610140527f636f6c6c61746572616c206f66666572206973206e6f74207a65726f000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b61012051614c66576001614c6e565b306101205118155b614cd7576020610140527f636f6c6c61746572616c20627579696e67206e6f7420617574686f72697a65646101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b606051638264fe986101405260805161016052803b15615a93575f610140602461015c5f855af1614d0a573d5f5f3e3d5ffd5b50565b604051636352211e60805260605160a052602060806024609c845afa614d35573d5f5f3e3d5ffd5b60203d10615a93576080518060a01c615a935760c05260c0905051815250565b60605163e985e9c560a05260405160c0523060e052602060a0604460bc845afa614d81573d5f5f3e3d5ffd5b60203d10615a935760a0518060011c615a935761010052610100905051614df4573060605163081812fc61012052608051610140526020610120602461013c845afa614dcf573d5f5f3e3d5ffd5b60203d10615a9357610120518060a01c615a9357610160526101609050511815614df7565b60015b815250565b60605163b88d4fde60c052608060405160e05230610100526080516101205280610140525f60a05260a08160e0015f81528051806020830101601f825f03163682375050601f19601f825160200101169050905081015050803b15615a93575f60c060a460dc5f855af1614e72573d5f5f3e3d5ffd5b50565b6020615b155f395f5160405114815250565b6102a051614ef4576015610300527f6164647220697320746865207a65726f206164647200000000000000000000006103205261030050610300518061032001601f825f031636823750506308c379a06102c05260206102e052601f19601f6103005101166044016102dcfd5b6102c051614f6157601c610300527f636f6c6c6174206164647220697320746865207a65726f2061646472000000006103205261030050610300518061032001601f825f031636823750506308c379a06102c05260206102e052601f19601f6103005101166044016102dcfd5b6102c051604052614f73610300614e75565b610300516150b5576102a0516102c0516040526102e051606052614f98610300614d0d565b61030051181561500757601e610320527f636f6c6c61746572616c206e6f74206f776e65642062792077616c6c657400006103405261032050610320518061034001601f825f031636823750506308c379a06102e052602061030052601f19601f6103205101166044016102fcfd5b6102a0516040526102c0516060526102e051608052615027610300614d55565b61030051615094576018610320527f7472616e73666572206973206e6f7420617070726f76656400000000000000006103405261032050610320518061034001601f825f031636823750506308c379a06102e052602061030052601f19601f6103205101166044016102fcfd5b6102a0516040526102c0516060526102e0516080526151eb614dfc566151eb565b6102a0516102c0516040526102e0516060526150d26103206148c3565b61032051181561514157601e610340527f636f6c6c61746572616c206e6f74206f776e65642062792077616c6c657400006103605261034050610340518061036001601f825f031636823750506308c379a061030052602061032052601f19601f61034051011660440161031cfd5b6102a0516040526102c0516060526102e05160805261516161032061490b565b610320516151ce576018610340527f7472616e73666572206973206e6f7420617070726f76656400000000000000006103605261034050610340518061036001601f825f031636823750506308c379a061030052602061032052601f19601f61034051011660440161031cfd5b6102a0516040526102c0516060526102e0516080526151eb6149fa565b565b6020615ad55f395f516323b872dd60a05260405160c05260605160e05260805161010052602060a0606460bc5f855af1615229573d5f5f3e3d5ffd5b60203d10615a935760a0518060011c615a9357610120526101209050516152af576013610140527f7472616e7366657246726f6d206661696c6564000000000000000000000000006101605261014050610140518061016001601f825f031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b565b6020615af55f395f5163b18e2bbb60c05260405160e05260605161010052608051610120525f6101405260a05161016052602060c060a460dc5f855af16152fa573d5f5f3e3d5ffd5b60203d10615a935760c05050565b6103e060406103e061086060045afa50615323610c406147a6565b610c40516002610860516020525f5260405f205414815250565b604051331861534d57600161536b565b6008336020525f5260405f2054615364575f61536b565b3260405118155b815250565b6103e0516153875760c0518152506153d8566153d8565b60c0514261012051808203828111615a935790509050808202811583838304141715615a9357905090506101005161012051808203828111615a9357905090508015615a9357808204905090508152505b565b604036610440375f610600525f6101c05160048111615a935780156154c457905b8060071b6101e0018051610620526020810151610640526040810151610660526060810151610680525061066051156154b9576104205161066051808202811583838304141715615a935790509050612710810490506106a0526104605160038111615a935760608102610480016106205181526106a051602082015261068051604082015250600181016104605250610440516106a051808201828110615a93579050905061044052600861062051186154b9576106a051610600525b6001018181186153fb575b5050610460516020606082020180838261046060045afa505050610440516101a0820152610600516101c082015250565b60066040516020525f5260405f20805460018103818111615a93579050815550565b6020615ad55f395f516323b872dd60805260405160a0523060c05260605160e052602060806064609c5f855af1615550573d5f5f3e3d5ffd5b60203d10615a93576080518060011c615a9357610100526101009050516155d4576013610120527f7472616e7366657246726f6d206661696c6564000000000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b565b6040366080376020615ad55f395f515a63a9059cbb60e4526004604051610104526060516101245260400160e05260e050602061018060e0516101005f8686f1905090506080523d602081183d602010021861016052610160805160a052602081015160c0525060805161564b57600161565a565b60c05160a05160200360031b1c155b156156b7577f1c43b9761b3fba5321ca8212bfc231945f668ccc0c446f333999eea9ce8fda8160405160e05260605161010052604060e0a160096040516020525f5260405f208054606051808201828110615a9357905090508155505b565b3061010051604052610120516060526156d36101406148c3565b61014051181561574257601d610160527f636f6c6c61746572616c206e6f74206f776e6564206279207661756c740000006101805261016050610160518061018001601f825f031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b61010051638b72a2ec6101405260e051610160526101205161018052803b15615a93575f610140604461015c5f855af161577e573d5f5f3e3d5ffd5b50565b30610100516040526101205160605261579b610140614d0d565b61014051181561580a57601d610160527f636f6c6c61746572616c206e6f74206f776e6564206279207661756c740000006101805261016050610160518061018001601f825f031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6101005163b88d4fde610160526080306101805260e0516101a052610120516101c052806101e0525f6101405261014081610180015f81528051806020830101601f825f03163682375050601f19601f825160200101169050905081015050803b15615a93575f61016060a461017c5f855af1615889573d5f5f3e3d5ffd5b50565b6102405160405261589e610280614e75565b610280516158c9576102205160e052610240516101005261026051610120526158e8615781566158e8565b6102205160e052610240516101005261026051610120526158e86156b9565b565b5f6106c0525f6101c05160048111615a9357801561594d57905b8060071b6101e00180516106e0526020810151610700526040810151610720526060810151610740525060086106e0511861594257610720516106c0525b600101818118615904575b50506106205161595f57610440615968565b5f610700526107005b516106e0526106205161597b575f6159b0565b60c05161068051808203828111615a9357905090506106c051808202811583838304141715615a935790509050612710810490505b6107005260c05161068051808203828111615a93579050905061072052610620516159dd57610440615a21565b610440516101005142808203828111615a935790509050808202811583838304141715615a935790509050610480518015615a935780820490509050610760526107605b51610740526106e0518060ff1c615a9357610740518060ff1c615a9357610720518060ff1c615a93578082038281135f831218615a935790509050610700518060ff1c615a93578082038281135f831218615a935790509050808281188284130218905090505f8112615a9357815250565b5f80fd11e5075c08193c8f3d0807db2a873b0f09081c683d083d0800643d083d0817103d0801023d0811a608e805a0077e00183d080493092a3d081175115315e8000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000447e69651d841bd8d104bed493000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb000000000000000000000000a11704b3dd545dc0771d9a9c5572064db2a5c06200000000000000000000000000000000000000000000000000000000000013880000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000013886d1b99f1a5c06364c839c0ed8aed09de5cb05b31a10190bbb613cede614558e4
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a11704b3dd545dc0771d9a9c5572064db2a5c06200000000000000000000000000000000000000447e69651d841bd8d104bed493000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007d96cc26566bfca358c61fbe7be3ca771da7ea60000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000013880000000000000000000000000000000000000000000000000000000000001388
-----Decoded View---------------
Arg [0] : _payment_token (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [1] : _p2p_control (address): 0xa11704B3dD545dC0771d9a9c5572064Db2A5C062
Arg [2] : _delegation_registry (address): 0x00000000000000447e69651d841bD8D104Bed493
Arg [3] : _cryptopunks (address): 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB
Arg [4] : _protocol_upfront_fee (uint256): 0
Arg [5] : _protocol_settlement_fee (uint256): 0
Arg [6] : _protocol_wallet (address): 0x07d96cC26566BFCA358C61fBe7be3Ca771Da7EA6
Arg [7] : _max_protocol_upfront_fee (uint256): 5000
Arg [8] : _max_protocol_settlement_fee (uint256): 5000
Arg [9] : _max_lender_broker_settlement_fee (uint256): 5000
Arg [10] : _max_borrower_broker_settlement_fee (uint256): 5000
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [1] : 000000000000000000000000a11704b3dd545dc0771d9a9c5572064db2a5c062
Arg [2] : 00000000000000000000000000000000000000447e69651d841bd8d104bed493
Arg [3] : 000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 00000000000000000000000007d96cc26566bfca358c61fbe7be3ca771da7ea6
Arg [7] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [8] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [9] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [10] : 0000000000000000000000000000000000000000000000000000000000001388
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.