Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 32,433 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Liquidate | 25511109 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25511067 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25511038 | 58 days ago | IN | 0 ETH | 0.00000005 | ||||
| Liquidate | 25510968 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25510950 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25510894 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Deposit | 16453176 | 224 days ago | IN | 0 ETH | 0.00000075 | ||||
| Withdraw | 16381836 | 227 days ago | IN | 0 ETH | 0.00000213 | ||||
| Withdraw | 16239480 | 233 days ago | IN | 0 ETH | 0.00000218 | ||||
| Withdraw | 16096489 | 239 days ago | IN | 0 ETH | 0.00000165 | ||||
| Withdraw | 16096431 | 239 days ago | IN | 0 ETH | 0.00000182 | ||||
| Withdraw | 16096402 | 239 days ago | IN | 0 ETH | 0.00000201 | ||||
| Withdraw | 16096342 | 239 days ago | IN | 0 ETH | 0.00000173 | ||||
| Withdraw | 16095239 | 239 days ago | IN | 0 ETH | 0.00000186 | ||||
| Withdraw | 16095227 | 239 days ago | IN | 0 ETH | 0.00000109 | ||||
| Withdraw | 16095211 | 239 days ago | IN | 0 ETH | 0.00000298 | ||||
| Withdraw | 16095197 | 239 days ago | IN | 0 ETH | 0.00000136 | ||||
| Withdraw | 16095142 | 239 days ago | IN | 0 ETH | 0.00000229 | ||||
| Withdraw | 16095011 | 239 days ago | IN | 0 ETH | 0.00000532 | ||||
| Withdraw | 16079809 | 239 days ago | IN | 0 ETH | 0.00000147 | ||||
| Withdraw | 16079798 | 239 days ago | IN | 0 ETH | 0.00000128 | ||||
| Withdraw | 16079782 | 239 days ago | IN | 0 ETH | 0.00000128 | ||||
| Withdraw | 16026793 | 241 days ago | IN | 0 ETH | 0.00000215 | ||||
| Withdraw | 15805866 | 246 days ago | IN | 0 ETH | 0.00000228 | ||||
| Withdraw | 15805857 | 246 days ago | IN | 0 ETH | 0.00000351 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 4726828 | 655 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CogPair
Compiler Version
vyper:0.3.10
Contract Source Code (Vyper language format)
# @version 0.3.10
"""
@title CogPair
@author cog.finance
@license GNU Affero General Public License v3.0
@notice Implementation of an isolated lending pool with PoL in Vyper
@dev ERC20 support for True/revert, return True/False, return None, ty Curve for the inspiration
"""
from vyper.interfaces import ERC20
from vyper.interfaces import ERC20Detailed
# ///////////////////////////////////////////////////// #
# Rebase Math Helpers #
# ///////////////////////////////////////////////////// #
struct Rebase:
elastic: uint128
base: uint128
@pure
@internal
def to_base_round_up(total: Rebase, elastic: uint256) -> uint256:
"""
@param total - The Rebase value which should be used to derive the relative base value
@param elastic - The elastic value to convert to a relative base value
@param round_up - Self explanatory
"""
if total.elastic == 0:
# If elastic is 0, then 0/n = 0 ∀ n ∈ R
return elastic
else:
# Base is equal to elastic * (total.base / total.elastic), essentially a ratio
base: uint256 = (elastic * convert(total.base, uint256)) / convert(
total.elastic, uint256
)
# mamushi: Exhibit 1
if (
(base * convert(total.elastic, uint256))
/ convert(total.base, uint256)
) < elastic:
base = base + 1
return base
@pure
@internal
def to_elastic(total: Rebase, base: uint256, round_up: bool) -> uint256:
"""
@param total - The Rebase which should be used to derive the relative elastic value
@param base - The base value to convert to a relative elastic value
@param round_up - Self explanatory
"""
if total.base == 0:
# If base is 0, then Rebase would be n/n, so elastic = base
return base
else:
# Elastic is equal to base * (total.elastic / total.base), essentially a ratio
elastic: uint256 = (base * convert(total.elastic, uint256)) / convert(
total.base, uint256
)
# mamushi: Exhibit 2
if round_up and (
(
(elastic * convert(total.base, uint256))
/ convert(total.elastic, uint256)
)
< base
):
elastic = elastic + 1
return elastic
@internal
def add_round_up(_total: Rebase, elastic: uint256) -> (Rebase, uint256):
"""
@notice Add `elastic` to `total` and doubles `total.base`
@param _total - The current total
@param elastic - The elastic value to add to the rebase
@param round_up - Self explanatory
@return - The new Rebase total
@return - The base in relationship to the elastic value
"""
total: Rebase = _total
base: uint256 = self.to_base_round_up(total, elastic)
total.elastic += convert(elastic, uint128)
total.base += convert(base, uint128)
return (total, base)
@internal
def sub(_total: Rebase, base: uint256, round_up: bool) -> (Rebase, uint256):
"""
@param _total - The current total
@param base - The base value to subtract from the rebase total
@param round_up - Self explanatory
@return - The new Rebase total
@return - The elastic in relationship to the base value
"""
total: Rebase = _total
elastic: uint256 = self.to_elastic(total, base, round_up)
total.elastic -= convert(elastic, uint128)
total.base -= convert(base, uint128)
return (total, elastic)
# ///////////////////////////////////////////////////// #
# Math Helper For Precision #
# ///////////////////////////////////////////////////// #
# Ty snekmate again
@pure
@internal
def mul_div(
x: uint256, y: uint256, denominator: uint256, roundup: bool
) -> uint256:
"""
@dev Calculates "(x * y) / denominator" in 512-bit precision,
following the selected rounding direction.
@notice The implementation is inspired by Remco Bloemen's
implementation under the MIT license here:
https://xn--2-umb.com/21/muldiv.
Furthermore, the rounding direction design pattern is
inspired by OpenZeppelin's implementation here:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol.
@param x The 32-byte multiplicand.
@param y The 32-byte multiplier.
@param denominator The 32-byte divisor.
@param roundup The Boolean variable that specifies whether
to round up or not. The default `False` is round down.
@return uint256 The 32-byte calculation result.
"""
# Handle division by zero.
assert denominator != empty(uint256), "Math: mul_div division by zero"
# 512-bit multiplication "[prod1 prod0] = x * y".
# Compute the product "mod 2**256" and "mod 2**256 - 1".
# Then use the Chinese Remainder theorem to reconstruct
# the 512-bit result. The result is stored in two 256-bit
# variables, where: "product = prod1 * 2**256 + prod0".
mm: uint256 = uint256_mulmod(x, y, max_value(uint256))
# The least significant 256 bits of the product.
prod0: uint256 = unsafe_mul(x, y)
# The most significant 256 bits of the product.
prod1: uint256 = empty(uint256)
if mm < prod0:
prod1 = unsafe_sub(unsafe_sub(mm, prod0), 1)
else:
prod1 = unsafe_sub(mm, prod0)
if prod1 == empty(uint256):
if roundup and uint256_mulmod(x, y, denominator) != empty(uint256):
# Calculate "ceil((x * y) / denominator)". The following
# line cannot overflow because we have the previous check
# "(x * y) % denominator != 0", which accordingly rules out
# the possibility of "x * y = 2**256 - 1" and `denominator == 1`.
return unsafe_add(unsafe_div(prod0, denominator), 1)
else:
return unsafe_div(prod0, denominator)
# Ensure that the result is less than 2**256. Also,
# prevents that `denominator == 0`.
assert denominator > prod1, "Math: mul_div overflow"
#######################
# 512 by 256 Division #
#######################
# Make division exact by subtracting the remainder
# from "[prod1 prod0]". First, compute remainder using
# the `uint256_mulmod` operation.
remainder: uint256 = uint256_mulmod(x, y, denominator)
# Second, subtract the 256-bit number from the 512-bit
# number.
if remainder > prod0:
prod1 = unsafe_sub(prod1, 1)
prod0 = unsafe_sub(prod0, remainder)
# Factor powers of two out of the denominator and calculate
# the largest power of two divisor of denominator. Always `>= 1`,
# unless the denominator is zero (which is prevented above),
# in which case `twos` is zero. For more details, please refer to:
# https://cs.stackexchange.com/q/138556.
twos: uint256 = unsafe_sub(0, denominator) & denominator
# Divide denominator by `twos`.
denominator_div: uint256 = unsafe_div(denominator, twos)
# Divide "[prod1 prod0]" by `twos`.
prod0 = unsafe_div(prod0, twos)
# Flip `twos` such that it is "2**256 / twos". If `twos` is zero,
# it becomes one.
twos = unsafe_add(unsafe_div(unsafe_sub(empty(uint256), twos), twos), 1)
# Shift bits from `prod1` to `prod0`.
prod0 |= unsafe_mul(prod1, twos)
# Invert the denominator "mod 2**256". Since the denominator is
# now an odd number, it has an inverse modulo 2**256, so we have:
# "denominator * inverse = 1 mod 2**256". Calculate the inverse by
# starting with a seed that is correct for four bits. That is,
# "denominator * inverse = 1 mod 2**4".
inverse: uint256 = unsafe_mul(3, denominator_div) ^ 2
# Use Newton-Raphson iteration to improve accuracy. Thanks to Hensel's
# lifting lemma, this also works in modular arithmetic by doubling the
# correct bits in each step.
inverse = unsafe_mul(
inverse, unsafe_sub(2, unsafe_mul(denominator_div, inverse))
) # Inverse "mod 2**8".
inverse = unsafe_mul(
inverse, unsafe_sub(2, unsafe_mul(denominator_div, inverse))
) # Inverse "mod 2**16".
inverse = unsafe_mul(
inverse, unsafe_sub(2, unsafe_mul(denominator_div, inverse))
) # Inverse "mod 2**32".
inverse = unsafe_mul(
inverse, unsafe_sub(2, unsafe_mul(denominator_div, inverse))
) # Inverse "mod 2**64".
inverse = unsafe_mul(
inverse, unsafe_sub(2, unsafe_mul(denominator_div, inverse))
) # Inverse "mod 2**128".
inverse = unsafe_mul(
inverse, unsafe_sub(2, unsafe_mul(denominator_div, inverse))
) # Inverse "mod 2**256".
# Since the division is now exact, we can divide by multiplying
# with the modular inverse of the denominator. This returns the
# correct result modulo 2**256. Since the preconditions guarantee
# that the result is less than 2**256, this is the final result.
# We do not need to calculate the high bits of the result and
# `prod1` is no longer necessary.
result: uint256 = unsafe_mul(prod0, inverse)
if roundup and uint256_mulmod(x, y, denominator) != empty(uint256):
# Calculate "ceil((x * y) / denominator)". The following
# line uses intentionally checked arithmetic to prevent
# a theoretically possible overflow.
result += 1
return result
# ///////////////////////////////////////////////////// #
# Interfaces #
# ///////////////////////////////////////////////////// #
# Oracle Interface
interface IOracle:
def get() -> (bool, uint256): nonpayable
# Factory Interface
interface ICogFactory:
def fee_to() -> address: view
# Cog Pair Specific Events
event AddCollateral:
to: indexed(address)
amount: indexed(uint256)
user_collateral_share: indexed(uint256)
event RemoveCollateral:
to: indexed(address)
amount: indexed(uint256)
user_collateral_share: indexed(uint256)
event Borrow:
amount: indexed(uint256)
to: indexed(address)
_from: indexed(address)
event Paused:
time: indexed(uint256)
event UnPaused:
time: indexed(uint256)
# ERC20 Events
event Transfer:
sender: indexed(address)
receiver: indexed(address)
amount: uint256
event Approval:
owner: indexed(address)
spender: indexed(address)
allowance: uint256
# ERC4626 Events
event Deposit:
depositor: indexed(address)
receiver: indexed(address)
assets: uint256
shares: uint256
event Withdraw:
withdrawer: indexed(address)
receiver: indexed(address)
owner: indexed(address)
assets: uint256
shares: uint256
# ///////////////////////////////////////////////////// #
# State Variables #
# ///////////////////////////////////////////////////// #
oracle: public(immutable(address)) # Address of the oracle
asset: public(immutable(address)) # Address of the asset
collateral: public(immutable(address)) # Address of the collateral
total_collateral_share: public(
uint256
) # Total collateral share of all borrowers
total_asset: public(
Rebase
) # Numerator is amount asset total, denominator keeps track of total shares of the asset
total_borrow: public(
Rebase
) # Numerator is the amount owed total, denominator keeps track of initial borrow shares owed
user_collateral_share: public(
HashMap[address, uint256]
) # Collateral share of each user
user_borrow_part: public(
HashMap[address, uint256]
) # Borrow ""share"" of each user
exchange_rate: public(uint256) # Exchange rate between asset and collateral
struct AccrueInfo:
interest_per_second: uint64
last_accrued: uint64
fees_earned_fraction: uint128
struct SurgeInfo:
last_interest_per_second: uint64
last_elapsed_time: uint64
accrue_info: public(AccrueInfo)
surge_info: public(SurgeInfo)
factory: public(immutable(address)) # Address of the factory
paused: public(bool) # Status of if the pool is paused
# ///////////////////////////////////////////////////// #
# Configuration Constants #
# ///////////////////////////////////////////////////// #
# SAFETY : EXCHANGE_RATE_PRECISION strictly must be > COLLATERIZATION_RATE_PRECISION or a divide by zero error will occur
# NOTE: Given they are also divided by each other, consider any potential precision loss as well
EXCHANGE_RATE_PRECISION: constant(uint256) = 1000000000000000000 # 1e18
COLLATERIZATION_RATE_PRECISION: constant(uint256) = 100000 # 1e5
COLLATERIZATION_RATE: constant(uint256) = 85000 # 85%
BORROW_OPENING_FEE: public(uint256)
BORROW_OPENING_FEE_PRECISION: constant(uint256) = 100000
# Starts at 10%, raised when PoL only mode is activated to PROTOCOL_FEE_PRECISION or 100%
protocol_fee: public(uint256)
DEFAULT_PROTOCOL_FEE: public(uint256)
PROTOCOL_FEE_PRECISION: constant(uint256) = 1000000
# If IR surges ~10% in 1 day then Protocol begins accruing PoL
# dr/dt, where dt = 3 days (86400 * 3), and dr is change in interest_rate per second or 3170979200 (5% interest rate)
PROTOCOL_SURGE_THRESHOLD: constant(uint64) = 1635979200
SURGE_DURATION: constant(uint64) = 86400 * 3 # 3 Days
UTILIZATION_PRECISION: constant(uint256) = 1000000000000000000 # 1e18
MINIMUM_TARGET_UTILIZATION: immutable(uint256)
MAXIMUM_TARGET_UTILIZATION: immutable(uint256)
FACTOR_PRECISION: constant(uint256) = 1000000000000000000 # 1e18
STARTING_INTEREST_PER_SECOND: immutable(uint64)
MINIMUM_INTEREST_PER_SECOND: immutable(uint64)
MAXIMUM_INTEREST_PER_SECOND: immutable(uint64)
INTEREST_ELASTICITY: immutable(uint256)
LIQUIDATION_MULTIPLIER: constant(uint256) = 112000 # 12
LIQUIDATION_MULTIPLIER_PRECISION: constant(uint256) = 100000 # 1e5
INTEREST_PER_SECOND_PRECISION: constant(uint256) = 1000000000000000000 # 1e18
# //////////////////////////////////////////////////////////////// #
# ERC20 #
# //////////////////////////////////////////////////////////////// #
balanceOf: public(HashMap[address, uint256])
@view
@external
def totalSupply() -> uint256:
"""
@return - Returns the total supply of the Asset Token, which is also the total number of shares
"""
return convert(self.total_asset.base, uint256)
allowance: public(HashMap[address, HashMap[address, uint256]])
NAME: constant(String[17]) = "Cog Pool LP Token"
@view
@external
def name() -> String[17]:
"""
@return The name for the ERC4626 Vault Token
"""
return NAME
SYMBOL: constant(String[3]) = "CLP"
@view
@external
def symbol() -> String[3]:
"""
@return The token symbol for the ERC4626 Vault Token
"""
return SYMBOL
DECIMALS: constant(uint8) = 18
@view
@external
def decimals() -> uint8:
"""
@return The number of decimals for the ERC4626 Vault Token
"""
return DECIMALS
@external
def transfer(receiver: address, amount: uint256) -> bool:
self.balanceOf[msg.sender] -= amount
self.balanceOf[receiver] += amount
log Transfer(msg.sender, receiver, amount)
return True
@external
def approve(spender: address, amount: uint256) -> bool:
self.allowance[msg.sender][spender] = amount
log Approval(msg.sender, spender, amount)
return True
@external
def transferFrom(sender: address, receiver: address, amount: uint256) -> bool:
self.allowance[sender][msg.sender] -= amount
self.balanceOf[sender] -= amount
self.balanceOf[receiver] += amount
log Transfer(sender, receiver, amount)
return True
# @t11s said I didn't need to support permit (https://twitter.com/transmissions11/status/1673478816168296450), so I removed it, if you need permit for something make a wrapper contract
# that kind of sounds like you problem tbh, it's just an LP token, make your users use 2 clicks it's not that hard
# ///////////////////////////////////////////////////// #
# ERC4626 Compatibility #
# ///////////////////////////////////////////////////// #
@view
@external
def totalAssets() -> uint256:
"""
@return - Returns the total amount of assets owned by the vault
"""
total_assets_elastic: uint256 = convert(self.total_asset.elastic, uint256)
# Borrowed assets are subtracted from the above total, so combined elastic values of both
# total borrow and total assets should be the same
total_borrow_elastic: uint256 = convert(self.total_borrow.elastic, uint256)
# Interest is the difference between elastic and base, since they start at 1:1
return total_borrow_elastic + total_assets_elastic
@view
@external
def convertToAssets(shareAmount: uint256) -> uint256:
"""
@param shareAmount - The amount of shares to convert to assets
@return - Returns the amount of assets returned given the amount of shares
"""
return self._convertToAssets(shareAmount)
@view
@internal
def _convertToAssets(shareAmount: uint256) -> uint256:
_total_asset: Rebase = self.total_asset
if _total_asset.base == 0:
# Shares mint 1:1 at the start until interest accrues
return shareAmount
all_share: uint256 = convert(
_total_asset.elastic + self.total_borrow.elastic, uint256
)
return shareAmount * all_share / convert(_total_asset.base, uint256)
@view
@external
def convertToShares(assetAmount: uint256) -> uint256:
"""
@param assetAmount - The amount of assets to convert to shares
@return - Returns the amount of shares returned given the amount of assets
"""
return self._convertToShares(assetAmount)
@view
@internal
def _convertToShares(assetAmount: uint256) -> uint256:
total_asset_base: uint256 = convert(self.total_asset.base, uint256)
all_share: uint256 = convert(
self.total_asset.elastic + self.total_borrow.elastic, uint256
)
if all_share == 0:
# Shares mint 1:1 at the start until interest accrues
return assetAmount
return assetAmount * total_asset_base / all_share
@view
@external
def maxDeposit(receiver: address) -> uint256:
"""
@param receiver - The address of the receiver
@return - Returns the maximum amount of assets that can be deposited into the vault
@notice - While technically there is no deposit cap, at unreasonably large uint256 values this may revert
"""
return max_value(uint256)
@view
@external
def previewDeposit(assets: uint256) -> uint256:
"""
@param assets - The amount of assets to deposit
@return - Returns the amount of shares that would be minted if the assets were deposited
"""
return self._convertToShares(assets)
@external
def deposit(assets: uint256, receiver: address = msg.sender) -> uint256:
"""
@param assets - The amount of assets to deposit
@param receiver - The address of the receiver
@return - Returns the amount of shares minted for the deposit
"""
self._is_not_paused()
shares_out: uint256 = self._add_asset(receiver, assets)
log Deposit(msg.sender, receiver, assets, shares_out)
return shares_out
@view
@external
def maxMint(owner: address) -> uint256:
"""
@notice no cap on max amount of shares to mint except at unreasonably high uint256 values
"""
return max_value(uint256)
@view
@external
def previewMint(shares: uint256) -> uint256:
"""
@param shares - The amount of shares to mint
@return - Returns the amount of assets required to mint the specified amount of shares
"""
# Convert shares to assets
return self._convertToAssets(shares)
@external
def mint(shares: uint256, receiver: address = msg.sender) -> uint256:
"""
@param shares - The amount of shares to mint
@param receiver - The address of the receiver
@return - The amount of assets used
"""
self._is_not_paused()
tokens_to_deposit: uint256 = self._convertToAssets(shares)
shares_out: uint256 = self._add_asset(receiver, tokens_to_deposit)
log Deposit(msg.sender, receiver, tokens_to_deposit, shares_out)
return tokens_to_deposit
@view
@external
def maxWithdraw(owner: address) -> uint256:
"""
@param owner - The address of the owner
@return - Returns the maximum amount of assets that can be withdrawn from the vault
"""
return min(
self._convertToAssets(self.balanceOf[owner]),
ERC20(asset).balanceOf(self),
)
@view
@external
def previewWithdraw(assets: uint256) -> uint256:
"""
@param assets - The amount of assets to withdraw
@return - The amount of shares worth withdrawn
@notice - Will revert if you try to preview withdrawing more assets than available currently in the vault's balance
"""
return min(self._convertToShares(assets), self._convertToShares(ERC20(asset).balanceOf(self)))
@external
def withdraw(
assets: uint256, receiver: address = msg.sender, owner: address = msg.sender
) -> uint256:
"""
@param assets - The amount of assets to withdraw
@param receiver - Reciever of the assets withdrawn
@param owner - The owners whose assets should be withdrawn
@return - The amount of shares burned
"""
self.efficient_accrue()
shares: uint256 = self._convertToShares(assets)
assets_withdraw: uint256 = self._remove_asset(receiver, owner, shares)
log Withdraw(msg.sender, receiver, owner, assets, shares)
return shares
@view
@external
def maxRedeem(owner: address) -> uint256:
"""
@param owner - The address of the owner
@return - Returns the maximum amount of shares that can be redeemed from the vault by the owner
"""
return min(
self.balanceOf[owner],
self._convertToShares(ERC20(asset).balanceOf(self)),
)
@view
@external
def previewRedeem(shares: uint256) -> uint256:
"""
@param shares - The amount of shares to redeem
@return - Returns the amount of assets that would be returned if the shares were redeemed
"""
return min(
self._convertToAssets(shares),
self._convertToShares(ERC20(asset).balanceOf(self)),
)
@external
def redeem(
shares: uint256, receiver: address = msg.sender, owner: address = msg.sender
) -> uint256:
"""
@param shares - The amount of shares to redeem
@param receiver - The address of the receiver
@param owner - The address of the owner
@return - The amount of assets returned
"""
self.efficient_accrue()
assets_out: uint256 = self._remove_asset(receiver, owner, shares)
log Withdraw(msg.sender, receiver, owner, assets_out, shares)
return assets_out
# ///////////////////////////////////////////////////// #
# Internal Implementations #
# ///////////////////////////////////////////////////// #
@internal
def _is_not_paused():
assert (not self.paused), "Pair Paused"
@internal
def efficient_accrue():
_accrue_info: AccrueInfo = self.accrue_info
elapsed_time: uint256 = block.timestamp - convert(
_accrue_info.last_accrued, uint256
)
if elapsed_time == 0:
# Prevents re-executing this logic if multiple actions are taken in the same block
return
self._accrue(_accrue_info, elapsed_time)
@internal
def _accrue(accrue_info: AccrueInfo, elapsed_time: uint256):
_accrue_info: AccrueInfo = accrue_info
_accrue_info.last_accrued = convert(block.timestamp, uint64)
_total_borrow: Rebase = self.total_borrow
if _total_borrow.base == 0:
# If there are no outstanding borrows, there is no need to accrue interest, and interest
# rate should be moved to minimum to encourage borrowing
if _accrue_info.interest_per_second != STARTING_INTEREST_PER_SECOND:
_accrue_info.interest_per_second = STARTING_INTEREST_PER_SECOND
self.accrue_info = _accrue_info
return
interest_accrued: uint256 = 0
fee_fraction: uint256 = 0
_total_asset: Rebase = self.total_asset
# Accrue interest
interest_accrued = (
convert(_total_borrow.elastic, uint256)
* convert(_accrue_info.interest_per_second, uint256)
* elapsed_time
/ INTEREST_PER_SECOND_PRECISION
)
_total_borrow.elastic = _total_borrow.elastic + convert(
interest_accrued, uint128
)
full_asset_amount: uint256 = convert(
_total_asset.elastic, uint256
) + convert(_total_borrow.elastic, uint256)
# Calculate fees
fee_amount: uint256 = (
interest_accrued * self.protocol_fee / PROTOCOL_FEE_PRECISION
) # % of interest paid goes to fee
fee_fraction = (
fee_amount * convert(_total_asset.base, uint256) / full_asset_amount
) # Update total fees earned
_accrue_info.fees_earned_fraction = (
_accrue_info.fees_earned_fraction + convert(fee_fraction, uint128)
)
# Fees should be considered in total assets
self.total_asset.base = _total_asset.base + convert(fee_fraction, uint128)
# Write new total borrow state to storage
self.total_borrow = _total_borrow
# Update interest rate
utilization: uint256 = (
convert(_total_borrow.elastic, uint256)
* UTILIZATION_PRECISION
/ full_asset_amount
)
if utilization < MINIMUM_TARGET_UTILIZATION:
under_factor: uint256 = (
(MINIMUM_TARGET_UTILIZATION - utilization)
* FACTOR_PRECISION
/ MINIMUM_TARGET_UTILIZATION
)
scale: uint256 = INTEREST_ELASTICITY + (
under_factor * under_factor * elapsed_time
)
new_interest_per_second: uint64 = convert(
convert(_accrue_info.interest_per_second, uint256)
* INTEREST_ELASTICITY
/ scale,
uint64,
)
_accrue_info.interest_per_second = new_interest_per_second
if _accrue_info.interest_per_second < MINIMUM_INTEREST_PER_SECOND:
_accrue_info.interest_per_second = (MINIMUM_INTEREST_PER_SECOND)
elif utilization > MAXIMUM_TARGET_UTILIZATION:
over_factor: uint256 = (
(utilization - MAXIMUM_TARGET_UTILIZATION)
* FACTOR_PRECISION
/ MAXIMUM_TARGET_UTILIZATION
)
scale: uint256 = INTEREST_ELASTICITY + (
over_factor * over_factor * elapsed_time
)
new_interest_per_second: uint64 = convert(
convert(_accrue_info.interest_per_second, uint256)
* scale
/ INTEREST_ELASTICITY,
uint64,
)
_accrue_info.interest_per_second = new_interest_per_second
if new_interest_per_second > MAXIMUM_INTEREST_PER_SECOND:
_accrue_info.interest_per_second = (MAXIMUM_INTEREST_PER_SECOND)
dt: uint64 = (
convert(block.timestamp, uint64) - self.surge_info.last_elapsed_time
)
if dt > SURGE_DURATION:
# if interest rate is increasing
if (
_accrue_info.interest_per_second
> self.surge_info.last_interest_per_second
):
# If daily change in interest rate is greater than Surge threshold, trigger surge breaker
dr: uint64 = (
_accrue_info.interest_per_second
- self.surge_info.last_interest_per_second
)
if dr > PROTOCOL_SURGE_THRESHOLD:
self.surge_info.last_elapsed_time = convert(
block.timestamp, uint64
)
self.surge_info.last_interest_per_second = (
_accrue_info.interest_per_second
)
# PoL Should accrue here, instead of to lenders, to discourage pid attacks as described in https://gauntlet.network/reports/pid
self.protocol_fee = PROTOCOL_FEE_PRECISION # 100% Protocol Fee
else:
# Reset protocol fee elsewise
self.protocol_fee = self.DEFAULT_PROTOCOL_FEE # 10% Protocol Fee
self.accrue_info = _accrue_info
@internal
def _add_collateral(to: address, amount: uint256):
"""
@param to The address to add collateral for
@param amount The amount of collateral to add, in tokens
"""
new_collateral_share: uint256 = self.user_collateral_share[to] + amount
self.user_collateral_share[to] = new_collateral_share
old_total_collateral_share: uint256 = self.total_collateral_share
self.total_collateral_share = old_total_collateral_share + amount
assert ERC20(collateral).transferFrom(
msg.sender, self, amount, default_return_value=True
) # dev: Transfer Failed
log AddCollateral(to, amount, new_collateral_share)
@internal
def _remove_collateral(to: address, amount: uint256):
"""
@param to The address to remove collateral for
@param amount The amount of collateral to remove, in tokens
"""
new_collateral_share: uint256 = self.user_collateral_share[msg.sender] - amount
self.user_collateral_share[msg.sender] = new_collateral_share
self.total_collateral_share = self.total_collateral_share - amount
assert ERC20(collateral).transfer(
to, amount, default_return_value=True
) # dev: Transfer Failed
log RemoveCollateral(to, amount, new_collateral_share)
@internal
def _add_asset(to: address, amount: uint256) -> uint256:
"""
@param to The address to add asset for
@param amount The amount of asset to add, in tokens
@return The amount of shares minted
"""
_total_asset: Rebase = self.total_asset
all_share: uint256 = convert(
_total_asset.elastic + self.total_borrow.elastic, uint256
)
fraction: uint256 = 0
if all_share == 0:
fraction = amount
else:
fraction = (amount * convert(_total_asset.base, uint256)) / all_share
if _total_asset.base + convert(fraction, uint128) < 1000:
return 0
self.total_asset = Rebase(
{
elastic: self.total_asset.elastic + convert(amount, uint128),
base: self.total_asset.base + convert(fraction, uint128),
}
)
new_balance: uint256 = self.balanceOf[to] + fraction
self.balanceOf[to] = new_balance
assert ERC20(asset).transferFrom(
msg.sender, self, amount, default_return_value=True
) # dev: Transfer Failed
return fraction
@internal
def _remove_asset(to: address, owner: address, share: uint256) -> uint256:
"""
@param to The address to remove asset for
@param share The amount of asset to remove, in shares
@return The amount of assets removed
"""
if owner != msg.sender:
assert (
self.allowance[owner][msg.sender] >= share
), "Insufficient Allowance"
self.allowance[owner][msg.sender] -= share
_total_asset: Rebase = self.total_asset
all_share: uint256 = convert(
_total_asset.elastic + self.total_borrow.elastic, uint256
)
amount: uint256 = (share * all_share) / convert(_total_asset.base, uint256)
_total_asset.elastic -= convert(amount, uint128)
_total_asset.base -= convert(share, uint128)
assert _total_asset.base >= 1000, "Below Minimum"
self.total_asset = _total_asset
new_balance: uint256 = self.balanceOf[owner] - share
self.balanceOf[owner] = new_balance
assert ERC20(asset).transfer(
to, amount, default_return_value=True
) # dev: Transfer Failed
return amount
@internal
def _update_exchange_rate() -> (bool, uint256):
"""
@return A tuple of (updated, rate)
updated: Whether the exchange rate was updated
rate: The exchange rate
"""
updated: bool = False
rate: uint256 = 0
updated, rate = IOracle(oracle).get()
if updated:
self.exchange_rate = rate
else:
rate = self.exchange_rate
return (updated, rate)
@internal
def _borrow(amount: uint256, _from: address, to: address) -> uint256:
"""
@param amount: The amount of asset to borrow, in tokens
@param _from: The account whom the loan should be taken out against
@param to: The address to send the borrowed tokens to
@return: The amount of tokens borrowed
"""
self._update_exchange_rate()
fee_amount: uint256 = (
amount * self.BORROW_OPENING_FEE
) / BORROW_OPENING_FEE_PRECISION
temp_total_borrow: Rebase = Rebase(
{
elastic: 0,
base: 0,
}
)
part: uint256 = 0
temp_total_borrow, part = self.add_round_up(
self.total_borrow, (amount + fee_amount)
)
self.total_borrow = temp_total_borrow
self.user_borrow_part[_from] = self.user_borrow_part[_from] + part
_total_asset: Rebase = self.total_asset
assert _total_asset.base >= 1000, "Below Minimum"
_total_asset.elastic = convert(
convert(_total_asset.elastic, uint256) - amount, uint128
)
self.total_asset = _total_asset
assert ERC20(asset).transfer(
to, amount, default_return_value=True
) # dev: Transfer Failed
log Borrow(amount, to, _from)
return amount
@internal
def _repay(payment: uint256) -> uint256:
"""
@param payment: The amount of asset to repay, in shares of the borrow position
@return: The amount of tokens repaid in shares
"""
temp_total_borrow: Rebase = Rebase(
{
elastic: 0,
base: 0,
}
)
amount: uint256 = 0
temp_total_borrow, amount = self.sub(self.total_borrow, payment, True)
self.total_borrow = temp_total_borrow
self.user_borrow_part[msg.sender] = self.user_borrow_part[msg.sender] - payment
total_share: uint128 = self.total_asset.elastic
assert ERC20(asset).transferFrom(
msg.sender, self, amount, default_return_value=True
) # dev: Transfer Failed
self.total_asset.elastic = total_share + convert(amount, uint128)
return amount
@internal
def _is_solvent(user: address, exchange_rate: uint256) -> bool:
"""
@param user: The user to check
@param exchange_rate: The exchange rate to use
@return: Whether the user is solvent
"""
borrow_part: uint256 = self.user_borrow_part[user]
if borrow_part == 0:
return True
collateral_share: uint256 = self.user_collateral_share[user]
if collateral_share == 0:
return False
_total_borrow: Rebase = self.total_borrow
collateral_amt: uint256 = (
(
collateral_share
* (EXCHANGE_RATE_PRECISION / COLLATERIZATION_RATE_PRECISION)
)
* COLLATERIZATION_RATE
)
borrow_part = self.mul_div(
(borrow_part * convert(_total_borrow.elastic, uint256)),
exchange_rate,
convert(_total_borrow.base, uint256),
False,
)
return collateral_amt >= borrow_part
# ///////////////////////////////////////////////////// #
# External Implementations #
# ///////////////////////////////////////////////////// #
@external
def __init__(
_asset: address,
_collateral: address,
_oracle: address,
min_target_utilization: uint256,
max_target_utilization: uint256,
starting_interest_per_second: uint64,
min_interest: uint64,
max_interest: uint64,
elasticity: uint256,
):
assert (
_collateral != 0x0000000000000000000000000000000000000000
), "Invalid Collateral"
collateral = _collateral
asset = _asset
oracle = _oracle
self.DEFAULT_PROTOCOL_FEE = 100000
self.protocol_fee = 100000 # 10%
MINIMUM_TARGET_UTILIZATION = min_target_utilization
MAXIMUM_TARGET_UTILIZATION = max_target_utilization
STARTING_INTEREST_PER_SECOND = starting_interest_per_second
MINIMUM_INTEREST_PER_SECOND = min_interest
MAXIMUM_INTEREST_PER_SECOND = max_interest
INTEREST_ELASTICITY = elasticity
self.BORROW_OPENING_FEE = 50
factory = msg.sender
@external
def accrue():
"""
@dev Accrues interest and updates the exchange rate if needed
"""
self.efficient_accrue()
@external
def add_collateral(to: address, amount: uint256):
"""
@param to The address to add collateral for
@param amount The amount of collateral to add, in tokens
"""
self.efficient_accrue()
self._add_collateral(to, amount)
@external
def remove_collateral(to: address, amount: uint256):
"""
@param to The address to remove collateral for
@param amount The amount of collateral to remove, in tokens
"""
self.efficient_accrue()
self._remove_collateral(to, amount)
assert self._is_solvent(
msg.sender, self.exchange_rate
), "Insufficient Collateral"
borrow_approvals: public(HashMap[address, HashMap[address, uint256]])
@external
def approve_borrow(borrower: address, amount: uint256) -> bool:
self.borrow_approvals[msg.sender][borrower] = amount
log Approval(msg.sender, borrower, amount)
return True
@external
def borrow(
amount: uint256, _from: address = msg.sender, to: address = msg.sender
) -> uint256:
"""
@param amount The amount of asset to borrow, in tokens
@param _from The account whom the loan should be taken out against
@param to The address to send the borrowed tokens to
@return The amount of tokens borrowed
"""
self._is_not_paused()
self.efficient_accrue()
if _from != msg.sender:
self.borrow_approvals[_from][msg.sender] -= amount
borrowed: uint256 = self._borrow(amount, _from, to)
assert self._is_solvent(
_from, self.exchange_rate
), "Insufficient Collateral"
# Now that utilization has changed, interest must be accrued to trigger any surge which now may be occuring
self._accrue(self.accrue_info, 0)
return borrowed
@external
def repay(payment: uint256) -> uint256:
"""
@param payment The amount of asset to repay, in debt position shares
@return The amount of tokens repaid in shares
"""
self.efficient_accrue()
return self._repay(payment)
@external
def get_exchange_rate() -> (bool, uint256):
"""
@return A tuple of (updated, rate)
updated Whether the exchange rate was updated
rate The exchange rate
"""
return self._update_exchange_rate()
@external
def liquidate(user: address, max_borrow_parts: uint256, to: address):
"""
@param user The user to liquidate
@param max_borrow_parts The parts to liquidate
@param to The address to send the liquidated tokens to
"""
exchange_rate: uint256 = 0
updated: bool = False # Never used
updated, exchange_rate = self._update_exchange_rate()
self.efficient_accrue()
collateral_share: uint256 = 0
borrow_amount: uint256 = 0
borrow_part: uint256 = 0
_total_borrow: Rebase = self.total_borrow
if not self._is_solvent(user, exchange_rate):
available_borrow_part: uint256 = self.user_borrow_part[user]
borrow_part = min(max_borrow_parts, available_borrow_part)
self.user_borrow_part[user] = available_borrow_part - borrow_part
borrow_amount = self.to_elastic(
_total_borrow, borrow_part, False
)
collateral_share = (
(borrow_amount * LIQUIDATION_MULTIPLIER * exchange_rate)
/ (LIQUIDATION_MULTIPLIER_PRECISION * EXCHANGE_RATE_PRECISION)
)
# NOTE: If this check is ever true, bad debt has accrued, and so the
# liquidator will instead receive collateral worth less than the assets
# they are paying, but the bad debt position will be resolved assuming the entire bad debt
# position is liquidated. Allows for bad debt positions to be liquidated
if collateral_share > self.user_collateral_share[user] and borrow_part == available_borrow_part:
collateral_share = self.user_collateral_share[user]
self.user_collateral_share[user] = (
self.user_collateral_share[user] - collateral_share
)
assert borrow_amount != 0, "CogPair: User is solvent"
self.total_borrow.elastic = self.total_borrow.elastic - convert(
borrow_amount, uint128
)
self.total_borrow.base = self.total_borrow.base - convert(
borrow_part, uint128
)
self.total_collateral_share = (
self.total_collateral_share - collateral_share
)
assert ERC20(collateral).transfer(
to, collateral_share, default_return_value=True
) # dev: Transfer failed
assert ERC20(asset).transferFrom(
msg.sender, self, borrow_amount, default_return_value=True
) # dev: Transfer failed
self.total_asset.elastic = self.total_asset.elastic + convert(
borrow_amount, uint128
)
# ///////////////////////////////////////////////////// #
# Tinkermaster Control Panel #
# ///////////////////////////////////////////////////// #
@external
def update_borrow_fee(newFee: uint256):
assert (msg.sender == factory)
assert (
newFee <= BORROW_OPENING_FEE_PRECISION / 2
) # Prevent rugging via borrow fee
self.BORROW_OPENING_FEE = newFee
@external
def update_default_protocol_fee(newFee: uint256):
assert (msg.sender == factory)
assert (newFee <= PROTOCOL_FEE_PRECISION)
self.DEFAULT_PROTOCOL_FEE = newFee
@external
def pause():
assert (msg.sender == factory)
self.paused = True
log Paused(block.timestamp)
@external
def unpause():
assert (msg.sender == factory)
self.paused = False
log UnPaused(block.timestamp)
@external
def roll_over_pol():
"""
@dev Withdraws protocol fees and deposits them into the pool on behalf of the tinkermaster address
"""
_fee_to: address = ICogFactory(factory).fee_to()
_accrue_info: AccrueInfo = self.accrue_info
# Withdraw protocol fees
fees_earned_fraction: uint256 = convert(
_accrue_info.fees_earned_fraction, uint256
)
self.balanceOf[_fee_to] = self.balanceOf[_fee_to] + fees_earned_fraction
self.accrue_info.fees_earned_fraction = 0
log Transfer(convert(0, address), _fee_to, fees_earned_fraction)Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"name":"AddCollateral","inputs":[{"name":"to","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":true},{"name":"user_collateral_share","type":"uint256","indexed":true}],"anonymous":false,"type":"event"},{"name":"RemoveCollateral","inputs":[{"name":"to","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":true},{"name":"user_collateral_share","type":"uint256","indexed":true}],"anonymous":false,"type":"event"},{"name":"Borrow","inputs":[{"name":"amount","type":"uint256","indexed":true},{"name":"to","type":"address","indexed":true},{"name":"_from","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"Paused","inputs":[{"name":"time","type":"uint256","indexed":true}],"anonymous":false,"type":"event"},{"name":"UnPaused","inputs":[{"name":"time","type":"uint256","indexed":true}],"anonymous":false,"type":"event"},{"name":"Transfer","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true},{"name":"spender","type":"address","indexed":true},{"name":"allowance","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Deposit","inputs":[{"name":"depositor","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"assets","type":"uint256","indexed":false},{"name":"shares","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Withdraw","inputs":[{"name":"withdrawer","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"owner","type":"address","indexed":true},{"name":"assets","type":"uint256","indexed":false},{"name":"shares","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8"}]},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"sender","type":"address"},{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"totalAssets","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"convertToAssets","inputs":[{"name":"shareAmount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"convertToShares","inputs":[{"name":"assetAmount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxDeposit","inputs":[{"name":"receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewDeposit","inputs":[{"name":"assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"assets","type":"uint256"},{"name":"receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxMint","inputs":[{"name":"owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewMint","inputs":[{"name":"shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"mint","inputs":[{"name":"shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"mint","inputs":[{"name":"shares","type":"uint256"},{"name":"receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxWithdraw","inputs":[{"name":"owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewWithdraw","inputs":[{"name":"assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"assets","type":"uint256"},{"name":"receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"assets","type":"uint256"},{"name":"receiver","type":"address"},{"name":"owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxRedeem","inputs":[{"name":"owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewRedeem","inputs":[{"name":"shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"redeem","inputs":[{"name":"shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"redeem","inputs":[{"name":"shares","type":"uint256"},{"name":"receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"redeem","inputs":[{"name":"shares","type":"uint256"},{"name":"receiver","type":"address"},{"name":"owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_asset","type":"address"},{"name":"_collateral","type":"address"},{"name":"_oracle","type":"address"},{"name":"min_target_utilization","type":"uint256"},{"name":"max_target_utilization","type":"uint256"},{"name":"starting_interest_per_second","type":"uint64"},{"name":"min_interest","type":"uint64"},{"name":"max_interest","type":"uint64"},{"name":"elasticity","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"accrue","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_collateral","inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"remove_collateral","inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"approve_borrow","inputs":[{"name":"borrower","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"borrow","inputs":[{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"borrow","inputs":[{"name":"amount","type":"uint256"},{"name":"_from","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"borrow","inputs":[{"name":"amount","type":"uint256"},{"name":"_from","type":"address"},{"name":"to","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"repay","inputs":[{"name":"payment","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"get_exchange_rate","inputs":[],"outputs":[{"name":"","type":"bool"},{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"liquidate","inputs":[{"name":"user","type":"address"},{"name":"max_borrow_parts","type":"uint256"},{"name":"to","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"update_borrow_fee","inputs":[{"name":"newFee","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"update_default_protocol_fee","inputs":[{"name":"newFee","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"pause","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"unpause","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"roll_over_pol","inputs":[],"outputs":[]},{"stateMutability":"view","type":"function","name":"oracle","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"asset","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"collateral","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"total_collateral_share","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"total_asset","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"elastic","type":"uint128"},{"name":"base","type":"uint128"}]}]},{"stateMutability":"view","type":"function","name":"total_borrow","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"elastic","type":"uint128"},{"name":"base","type":"uint128"}]}]},{"stateMutability":"view","type":"function","name":"user_collateral_share","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"user_borrow_part","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"exchange_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"accrue_info","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"interest_per_second","type":"uint64"},{"name":"last_accrued","type":"uint64"},{"name":"fees_earned_fraction","type":"uint128"}]}]},{"stateMutability":"view","type":"function","name":"surge_info","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"last_interest_per_second","type":"uint64"},{"name":"last_elapsed_time","type":"uint64"}]}]},{"stateMutability":"view","type":"function","name":"factory","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"paused","inputs":[],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"BORROW_OPENING_FEE","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"protocol_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"DEFAULT_PROTOCOL_FEE","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"borrow_approvals","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}]}]Contract Creation Code
612f53515034610165576020612fb35f395f518060a01c610165576040526020612fd35f395f518060a01c610165576060526020612ff35f395f518060a01c6101655760805260206130535f395f518060401c6101655760a05260206130735f395f518060401c6101655760c05260206130935f395f518060401c6101655760e0526060516100ea576012610100527f496e76616c696420436f6c6c61746572616c00000000000000000000000000006101205261010050610100518061012001601f825f031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b606051612e7352604051612e5352608051612e3352620186a0601055620186a0600f5560206130135f395f51612eb35260206130335f395f51612ed35260a051612ef35260c051612f135260e051612f335260206130b35f395f51612f53526032600e5533612e9352612e3361016961000039612f73610000f35b5f80fd5f3560e01c6002603a820660011b612dbf01601e395f51565b637dc0d1d081186117655734612dbb576020612e3360403960206040f3611765565b6338d52e0f81186100585734612dbb576020612e5360403960206040f35b63dba2d553811861176557602436103417612dbb576020612e935f395f513318612dbb5761c35060043511612dbb57600435600e5500611765565b63d8dfeb4581186100b15734612dbb576020612e7360403960206040f35b6306fdde03811861012f5734612dbb5760208060805260116040527f436f6720506f6f6c204c5020546f6b656e00000000000000000000000000000060605260408160800181518152602082015160208201528051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b63f8ba4cff81186117655734612dbb57610147612440565b00611765565b631ac0e29281186101685734612dbb575f5460405260206040f35b63fe9f6e2481186117655734612dbb5760406101856101206128f7565b610120f3611765565b636b8833c981186117655734612dbb5760015460405260025460605260406040f3611765565b638274109781186117655734612dbb5760035460405260045460605260406040f3611765565b632b5fca1d811861021557602436103417612dbb576004358060a01c612dbb5760405260056040516020525f5260405f205460605260206060f35b6323b872dd811861176557606436103417612dbb576004358060a01c612dbb576040526024358060a01c612dbb5760605260126040516020525f5260405f2080336020525f5260405f2090508054604435808203828111612dbb579050905081555060116040516020525f5260405f208054604435808203828111612dbb579050905081555060116060516020525f5260405f208054604435808201828110612dbb57905090508155506060516040517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60443560805260206080a3600160805260206080f3611765565b6377917072811861033b57602436103417612dbb576004358060a01c612dbb5760405260066040516020525f5260405f205460605260206060f35b634c01b790811861176557604436103417612dbb576004358060a01c612dbb576040526024356013336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f3611765565b63171ef0b281186103d85734612dbb5760075460405260206040f35b63648c587481186103f45734612dbb5760105460405260206040f35b634b3fd148811861176557604436103417612dbb576024358060a01c612dbb5761034052336103605261118956611765565b633f0bc5bc811861044e5734612dbb57600854604052600954606052600a5460805260606040f35b6316552732811861046a5734612dbb57600f5460405260206040f35b6307a2d13a811861176557602436103417612dbb57602060043560405261049160c0611cd6565b60c0f3611765565b6363eded9581186117655734612dbb57600b54604052600c5460605260406040f3611765565b63c45a015581186117655734612dbb576020612e9360403960206040f3611765565b635c975abb81186117655734612dbb57600d5460405260206040f3611765565b63aba024f481186117655734612dbb57600e5460405260206040f3611765565b6370a08231811861055c57602436103417612dbb576004358060a01c612dbb5760405260116040516020525f5260405f205460605260206060f35b63b6b55f25811861176557602436103417612dbb57336101c05261096a56611765565b6318160ddd811861059b5734612dbb5760025460405260206040f35b63ef8b30f7811861176557602436103417612dbb5760206004356040526105c260a0611d3c565b60a0f3611765565b63dd62ed3e811861176557604436103417612dbb576004358060a01c612dbb576040526024358060a01c612dbb5760605260126040516020525f5260405f20806060516020525f5260405f2090505460805260206080f3611765565b6395d89b4181186106a45734612dbb5760208060805260036040527f434c50000000000000000000000000000000000000000000000000000000000060605260408160800181518152602082015160208201528051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b63ce96cb77811861176557602436103417612dbb576004358060a01c612dbb5760c052601160c0516020525f5260405f20546040526106e360e0611cd6565b60e0516020612e535f395f516370a082316101005230610120526020610100602461011c845afa610716573d5f5f3e3d5ffd5b60203d10612dbb5761010090505180828118828410021890509050610140526020610140f3611765565b63313ce56781186117655734612dbb57601260405260206040f3611765565b63a9059cbb811861176557604436103417612dbb576004358060a01c612dbb576040526011336020525f5260405f208054602435808203828111612dbb579050905081555060116040516020525f5260405f208054602435808201828110612dbb5790509050815550604051337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60243560605260206060a3600160605260206060f3611765565b63095ea7b3811861176557604436103417612dbb576004358060a01c612dbb576040526024356012336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f3611765565b6301e1d11481186117655734612dbb57600154604052600354606052606051604051808201828110612dbb579050905060805260206080f3611765565b63c6e6f592811861176557602436103417612dbb5760206004356040526108ec60a0611d3c565b60a0f3611765565b63402d267d811861176557602436103417612dbb576004358060a01c612dbb576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f3611765565b636e553f6581186109d457604436103417612dbb576024358060a01c612dbb576101c0525b610972611d9c565b6101c05160405260043560605261098a610200611e01565b610200516101e0526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7600435610200526101e051610220526040610200a360206101e0f35b63b3d7f6b9811861176557602436103417612dbb5760206004356040526109fb60c0611cd6565b60c0f3611765565b63c63d75b68118610a5057602436103417612dbb576004358060a01c612dbb576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63c5ebeaec8118610a7457602436103417612dbb5733610340523361036052611189565b635ec8ede4811861176557602436103417612dbb576020612e935f395f513318612dbb57620f424060043511612dbb5760043560105500611765565b63a0712d688118610acf57602436103417612dbb57336101c052610b25565b62f714ce811861176557604436103417612dbb576024358060a01c612dbb57610320523361034052610d2856611765565b6394bf804d8118610baa57604436103417612dbb576024358060a01c612dbb576101c0525b610b2d611d9c565b600435604052610b3e610200611cd6565b610200516101e0526101c0516040526101e051606052610b5f610220611e01565b61022051610200526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d76101e0516102205261020051610240526040610220a360206101e0f35b6314fa10e1811861176557604436103417612dbb576004358060a01c612dbb5761032052610bd6612440565b61032051604052602435606052610beb61271f565b00611765565b630a28a477811861176557602436103417612dbb57600435604052610c1660a0611d3c565b60a0516020612e535f395f516370a0823160c0523060e052602060c0602460dc845afa610c45573d5f5f3e3d5ffd5b60203d10612dbb5760c0905051604052610c60610100611d3c565b6101005180828118828410021890509050610120526020610120f3611765565b632e1a7d4d8118610ca457602436103417612dbb5733610320523361034052610d28565b638456cb5981186117655734612dbb576020612e935f395f513318612dbb576001600d55427f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e5f6040a200611765565b63b460af948118610db757606436103417612dbb576024358060a01c612dbb57610320526044358060a01c612dbb57610340525b610d30612440565b600435604052610d41610380611d3c565b6103805161036052610320516040526103405160605261036051608052610d696103a061249f565b6103a051610380526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db6004356103a052610360516103c05260406103a0a46020610360f35b634cdad506811861176557602436103417612dbb57600435604052610ddc60c0611cd6565b60c0516020612e535f395f516370a0823160e0523061010052602060e0602460fc845afa610e0c573d5f5f3e3d5ffd5b60203d10612dbb5760e0905051604052610e27610120611d3c565b6101205180828118828410021890509050610140526020610140f3611765565b63d905777e811861176557602436103417612dbb576004358060a01c612dbb5760a052601160a0516020525f5260405f20546020612e535f395f516370a0823160c0523060e052602060c0602460dc845afa610ea5573d5f5f3e3d5ffd5b60203d10612dbb5760c0905051604052610ec0610100611d3c565b6101005180828118828410021890509050610120526020610120f3611765565b63db006a758118610f0457602436103417612dbb5733610320523361034052611080565b63b5effcf3811861176557604436103417612dbb576004358060a01c612dbb5761032052610f30612440565b61032051604052602435606052610f45612812565b336101c0526007546101e052610f5c610340612cd8565b61034051610fc9576017610360527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103805261036050610360518061038001601f825f031636823750506308c379a061032052602061034052601f19601f61036051011660440161033cfd5b00611765565b637bde82f28118610ffd57604436103417612dbb576024358060a01c612dbb57610320523361034052611080565b633f4ba83a81186117655734612dbb576020612e935f395f513318612dbb575f600d55427fb96cc4c95dd57612feeeaed56e65b2fd6ba67b101d0592527f05756fafcab4b45f6040a200611765565b63ba087652811861176557606436103417612dbb576024358060a01c612dbb57610320526044358060a01c612dbb57610340525b611088612440565b61032051604052610340516060526004356080526110a761038061249f565b61038051610360526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db61036051610380526004356103a0526040610380a46020610360f3611765565b6332874ec7811861176557604436103417612dbb576004358060a01c612dbb576040526024358060a01c612dbb5760605260136040516020525f5260405f20806060516020525f5260405f2090505460805260206080f3611765565b63d516418481186112ac57606436103417612dbb576024358060a01c612dbb57610340526044358060a01c612dbb57610360525b611191611d9c565b611199612440565b3361034051146111d6576013610340516020525f5260405f2080336020525f5260405f2090508054600435808203828111612dbb57905090508155505b6004356101a052610340516101c052610360516101e0526111f86103a061297e565b6103a05161038052610340516101c0526007546101e05261121a6103a0612cd8565b6103a0516112875760176103c0527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103e0526103c0506103c051806103e001601f825f031636823750506308c379a06103805260206103a052601f19601f6103c051011660440161039cfd5b600854604052600954606052600a546080525f60a0526112a5611f9f565b6020610380f35b631c12948e81186117655734612dbb576020612e935f395f516326cfa27c606052602060606004607c845afa6112e4573d5f5f3e3d5ffd5b60203d10612dbb576060518060a01c612dbb5760a05260a0905051604052600854606052600954608052600a5460a05260a05160c05260116040516020525f5260405f205460c051808201828110612dbb579050905060116040516020525f5260405f20555f600a556040515f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60c05160e052602060e0a300611765565b63371fd8e6811861176557602436103417612dbb576113a0612440565b60206004356101e0526113b4610320612baa565b610320f3611765565b634914c008811861176557606436103417612dbb576004358060a01c612dbb57610320526044358060a01c612dbb5761034052604036610360376114026103a06128f7565b6103a08051610380526020810151610360525061141d612440565b6060366103a0376003546104005260045461042052610320516101c052610360516101e05261144d610440612cd8565b6104405161158d576006610320516020525f5260405f20546104605260243561046051808281188284100218905090506103e052610460516103e051808203828111612dbb57905090506006610320516020525f5260405f205561040051604052610420516060526103e0516080525f60a0526114cb6104806117fc565b610480516103c0526103c0516201b5808102816201b580820418612dbb57905061036051808202811583838304141715612dbb579050905069152d02c7e14af6800000810490506103a0526005610320516020525f5260405f20546103a05111611535575f611540565b610460516103e05118155b1561155a576005610320516020525f5260405f20546103a0525b6005610320516020525f5260405f20546103a051808203828111612dbb57905090506005610320516020525f5260405f20555b6103c0516115fa576018610440527f436f67506169723a205573657220697320736f6c76656e7400000000000000006104605261044050610440518061046001601f825f031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b6003546103c0518060801c612dbb578082038060801c612dbb57905090506003556004546103e0518060801c612dbb578082038060801c612dbb57905090506004555f546103a051808203828111612dbb57905090505f556020612e735f395f5163a9059cbb6104405261034051610460526103a051610480526020610440604461045c5f855af161168e573d5f5f3e3d5ffd5b3d6116a557803b15612dbb5760016104a0526116be565b60203d10612dbb57610440518060011c612dbb576104a0525b6104a090505115612dbb576020612e535f395f516323b872dd61044052336104605230610480526103c0516104a0526020610440606461045c5f855af1611707573d5f5f3e3d5ffd5b3d61171e57803b15612dbb5760016104c052611737565b60203d10612dbb57610440518060011c612dbb576104c0525b6104c090505115612dbb576001546103c0518060801c612dbb578082018060801c612dbb5790509050600155005b5f5ffd5b60405161177f576080518152506117fa566117fa565b608051606051808202811583838304141715612dbb57905090506040518015612dbb578082049050905060a05260805160a051604051808202811583838304141715612dbb57905090506060518015612dbb578082049050905010156117f35760a05160018101818110612dbb57905060a0525b60a0518152505b565b6060516118125760805181525061189b5661189b565b608051604051808202811583838304141715612dbb57905090506060518015612dbb578082049050905060c05260a05161184c575f61187b565b60805160c051606051808202811583838304141715612dbb57905090506040518015612dbb5780820490509050105b156118945760c05160018101818110612dbb57905060c0525b60c0518152505b565b60c0516101205260e051610140526101205160405261014051606052610100516080526118cb610180611769565b610180516101605261012051610100518060801c612dbb578082018060801c612dbb57905090506101205261014051610160518060801c612dbb578082018060801c612dbb57905090506101405261012051815261014051602082015261016051604082015250565b60e0516101605261010051610180526101605160405261018051606052610120516080526101405160a05261196a6101c06117fc565b6101c0516101a052610160516101a0518060801c612dbb578082038060801c612dbb57905090506101605261018051610120518060801c612dbb578082038060801c612dbb5790509050610180526101605181526101805160208201526101a051604082015250565b608051611a3657601e60c0527f4d6174683a206d756c5f646976206469766973696f6e206279207a65726f000060e05260c05060c0518060e001601f825f031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b6040516060517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183099050905060c0526060516040510260e0525f6101005260e05160c05110611a915760e05160c0510361010052611aa0565b600160e05160c0510303610100525b61010051611afa5760a051611ab5575f611ad1565b6040516060516080518015612dbb578082840990509050905015155b611ae85760805160e05104815250611cd456611afa565b600160805160e0510401815250611cd4565b6101005160805111611b69576016610120527f4d6174683a206d756c5f646976206f766572666c6f77000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6040516060516080518015612dbb57808284099050905090506101205260e051610120511115611b9f5760016101005103610100525b6101205160e0510360e0526080516080515f0316610140526101405160805104610160526101405160e0510460e052600161014051610140515f0304016101405261014051610100510260e0511760e05260026101605160030218610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805160e051026101a05260a051611c95575f611cb1565b6040516060516080518015612dbb578082840990509050905015155b15611ccc576101a05160018101818110612dbb5790506101a0525b6101a0518152505b565b600154606052600254608052608051611cf457604051815250611d3a565b6060516003548082018060801c612dbb579050905060a05260405160a051808202811583838304141715612dbb57905090506080518015612dbb57808204905090508152505b565b6002546060526001546003548082018060801c612dbb5790509050608052608051611d6c57604051815250611d9a565b604051606051808202811583838304141715612dbb57905090506080518015612dbb57808204905090508152505b565b600d5415611dff57600b6040527f506169722050617573656400000000000000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b565b60015460805260025460a0526080516003548082018060801c612dbb579050905060c0525f60e05260c051611e3b5760605160e052611e69565b60605160a051808202811583838304141715612dbb579050905060c0518015612dbb578082049050905060e0525b6103e760a05160e0518060801c612dbb578082018060801c612dbb579050905013611e97575f815250611f9d565b6001546060518060801c612dbb578082018060801c612dbb57905090506101005260025460e0518060801c612dbb578082018060801c612dbb579050905061012052610100516001556101205160025560116040516020525f5260405f205460e051808201828110612dbb5790509050610100526101005160116040516020525f5260405f20556020612e535f395f516323b872dd6101205233610140523061016052606051610180526020610120606461013c5f855af1611f5b573d5f5f3e3d5ffd5b3d611f7257803b15612dbb5760016101a052611f8b565b60203d10612dbb57610120518060011c612dbb576101a0525b6101a090505115612dbb5760e0518152505b565b60405160c05260605160e05260805161010052428060401c612dbb5760e052600354610120526004546101405261014051612006576020612ef35f395f5160c05114611fee576020612ef360c0395b60c05160085560e05160095561010051600a5561243e565b604036610160376001546101a0526002546101c0526101205160c051808202811583838304141715612dbb579050905060a051808202811583838304141715612dbb5790509050670de0b6b3a7640000810490506101605261012051610160518060801c612dbb578082018060801c612dbb5790509050610120526101a05161012051808201828110612dbb57905090506101e05261016051600f54808202811583838304141715612dbb5790509050620f42408104905061020052610200516101c051808202811583838304141715612dbb57905090506101e0518015612dbb57808204905090506101805261010051610180518060801c612dbb578082018060801c612dbb5790509050610100526101c051610180518060801c612dbb578082018060801c612dbb5790509050600255610120516003556101405160045561012051670de0b6b3a7640000810281670de0b6b3a7640000820418612dbb5790506101e0518015612dbb5780820490509050610220526020612eb35f395f5161022051106122a7576020612ed35f395f516102205111156123a757610220516020612ed35f395f51808203828111612dbb5790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612dbb5790506020612ed35f395f518015612dbb5780820490509050610240526020612f535f395f516102405161024051808202811583838304141715612dbb579050905060a051808202811583838304141715612dbb5790509050808201828110612dbb57905090506102605260c05161026051808202811583838304141715612dbb57905090506020612f535f395f518015612dbb57808204905090508060401c612dbb57610280526102805160c0526020612f335f395f516102805113156123a7576020612f3360c0396123a7565b6020612eb35f395f5161022051808203828111612dbb5790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612dbb5790506020612eb35f395f518015612dbb5780820490509050610240526020612f535f395f516102405161024051808202811583838304141715612dbb579050905060a051808202811583838304141715612dbb5790509050808201828110612dbb57905090506102605260c0516020612f535f395f51808202811583838304141715612dbb5790509050610260518015612dbb57808204905090508060401c612dbb57610280526102805160c0526020612f135f395f5160c05112156123a7576020612f1360c0395b428060401c612dbb57600c548082038060401c612dbb5790509050610240526203f481610240511261242a57600b5460c051136123e957601054600f5561242a565b60c051600b548082038060401c612dbb5790509050610260526361830fc1610260511261242a57428060401c612dbb57600c5560c051600b55620f4240600f555b60c05160085560e05160095561010051600a555b565b6008546102a0526009546102c052600a546102e052426102c051808203828111612dbb579050905061030052610300516124795761249d565b6102a0516040526102c0516060526102e0516080526103005160a05261249d611f9f565b565b336060511461255b5760805160126060516020525f5260405f2080336020525f5260405f20905054101561252957601660a0527f496e73756666696369656e7420416c6c6f77616e63650000000000000000000060c05260a05060a0518060c001601f825f031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b60126060516020525f5260405f2080336020525f5260405f2090508054608051808203828111612dbb57905090508155505b60015460a05260025460c05260a0516003548082018060801c612dbb579050905060e05260805160e051808202811583838304141715612dbb579050905060c0518015612dbb57808204905090506101005260a051610100518060801c612dbb578082038060801c612dbb579050905060a05260c0516080518060801c612dbb578082038060801c612dbb579050905060c0526103e860c051121561265d57600d610120527f42656c6f77204d696e696d756d000000000000000000000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60a05160015560c05160025560116060516020525f5260405f2054608051808203828111612dbb5790509050610120526101205160116060516020525f5260405f20556020612e535f395f5163a9059cbb610140526040516101605261010051610180526020610140604461015c5f855af16126db573d5f5f3e3d5ffd5b3d6126f257803b15612dbb5760016101a05261270b565b60203d10612dbb57610140518060011c612dbb576101a0525b6101a090505115612dbb5761010051815250565b60056040516020525f5260405f2054606051808201828110612dbb579050905060805260805160056040516020525f5260405f20555f5460a05260a051606051808201828110612dbb57905090505f556020612e735f395f516323b872dd60c0523360e052306101005260605161012052602060c0606460dc5f855af16127a8573d5f5f3e3d5ffd5b3d6127bf57803b15612dbb576001610140526127d7565b60203d10612dbb5760c0518060011c612dbb57610140525b61014090505115612dbb576080516060516040517fe3f4fa74d049cf7d64965afd6ce83c826cd313cec824ecfb9aacf36886090b495f60c0a4565b6005336020525f5260405f2054606051808203828111612dbb57905090506080526080516005336020525f5260405f20555f54606051808203828111612dbb57905090505f556020612e735f395f5163a9059cbb60a05260405160c05260605160e052602060a0604460bc5f855af161288d573d5f5f3e3d5ffd5b3d6128a457803b15612dbb576001610100526128bc565b60203d10612dbb5760a0518060011c612dbb57610100525b61010090505115612dbb576080516060516040517fdec5d726a70bdc7ab7e167507e34e068ab89db504d9ddcb08618c73a1f10a93e5f60a0a4565b6040366040376020612e335f395f51636d4ce63c608052604060806004609c5f855af1612926573d5f5f3e3d5ffd5b60403d10612dbb576080518060011c612dbb5760e05260a0516101005260e0905080516040526020810151606052506040516129675760075460605261296e565b6060516007555b6040518152606051602082015250565b6129896102006128f7565b610200506101a051600e54808202811583838304141715612dbb5790509050620186a081049050610200526060366102203760035460c05260045460e0526101a05161020051808201828110612dbb5790509050610100526129ec61028061189d565b61028080516102205260208101516102405260408101516102605250610220516003556102405160045560066101c0516020525f5260405f205461026051808201828110612dbb579050905060066101c0516020525f5260405f2055600154610280526002546102a0526103e86102a0511215612ac857600d6102c0527f42656c6f77204d696e696d756d000000000000000000000000000000000000006102e0526102c0506102c051806102e001601f825f031636823750506308c379a06102805260206102a052601f19601f6102c051011660440161029cfd5b610280516101a051808203828111612dbb57905090508060801c612dbb5761028052610280516001556102a0516002556020612e535f395f5163a9059cbb6102c0526101e0516102e0526101a0516103005260206102c060446102dc5f855af1612b34573d5f5f3e3d5ffd5b3d612b4b57803b15612dbb57600161032052612b64565b60203d10612dbb576102c0518060011c612dbb57610320525b61032090505115612dbb576101c0516101e0516101a0517f322a69e46c4e1be12df82297341b3c5651c9f47519342541b412514bed8aac895f6102c0a46101a051815250565b6060366102003760035460e052600454610100526101e05161012052600161014052612bd7610260611934565b6102608051610200526020810151610220526040810151610240525061020051600355610220516004556006336020525f5260405f20546101e051808203828111612dbb57905090506006336020525f5260405f2055600154610260526020612e535f395f516323b872dd61028052336102a052306102c052610240516102e0526020610280606461029c5f855af1612c72573d5f5f3e3d5ffd5b3d612c8957803b15612dbb57600161030052612ca2565b60203d10612dbb57610280518060011c612dbb57610300525b61030090505115612dbb5761026051610240518060801c612dbb578082018060801c612dbb579050905060015561024051815250565b60066101c0516020525f5260405f20546102005261020051612cfe576001815250612db9565b60056101c0516020525f5260405f20546102205261022051612d23575f815250612db9565b6003546102405260045461026052610220516509184e72a0008102816509184e72a000820418612dbb57905062014c0881028162014c08820418612dbb579050610280526102005161024051808202811583838304141715612dbb57905090506040526101e051606052610260516080525f60a052612da36102a06119d3565b6102a05161020052610200516102805110158152505b565b5f80fd17651765050101b40fcf018e11550c8017650b00138317651765052103bc04bf1765074008c51765030001da13bd0ee00cf404991765176517651765176500931765176505ca0bf10a0310f9088817651765075f04260626014d04e10ab00807104c08f4176509450e47003a0018057f1765176584192e33811874190140a16576797065728300030a00170000000000000000000000005300000000000000000000000000000000000004000000000000000000000000a25b25548b4c98b0c7d3d27dca5d5ca743d68b7f000000000000000000000000480501d16841181d267a3a40b5b1f0126473ab3100000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000009b6e64a8ec60000000000000000000000000000000000000000000000000000000000005e80a6c00000000000000000000000000000000000000000000000000000000025cd0f80000000000000000000000000000000000000000000000000000000023703e88000000000000000000000000000000054a2b63d65d79d094abb66880000000000
Deployed Bytecode
0x5f3560e01c6002603a820660011b612dbf01601e395f51565b637dc0d1d081186117655734612dbb576020612e3360403960206040f3611765565b6338d52e0f81186100585734612dbb576020612e5360403960206040f35b63dba2d553811861176557602436103417612dbb576020612e935f395f513318612dbb5761c35060043511612dbb57600435600e5500611765565b63d8dfeb4581186100b15734612dbb576020612e7360403960206040f35b6306fdde03811861012f5734612dbb5760208060805260116040527f436f6720506f6f6c204c5020546f6b656e00000000000000000000000000000060605260408160800181518152602082015160208201528051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b63f8ba4cff81186117655734612dbb57610147612440565b00611765565b631ac0e29281186101685734612dbb575f5460405260206040f35b63fe9f6e2481186117655734612dbb5760406101856101206128f7565b610120f3611765565b636b8833c981186117655734612dbb5760015460405260025460605260406040f3611765565b638274109781186117655734612dbb5760035460405260045460605260406040f3611765565b632b5fca1d811861021557602436103417612dbb576004358060a01c612dbb5760405260056040516020525f5260405f205460605260206060f35b6323b872dd811861176557606436103417612dbb576004358060a01c612dbb576040526024358060a01c612dbb5760605260126040516020525f5260405f2080336020525f5260405f2090508054604435808203828111612dbb579050905081555060116040516020525f5260405f208054604435808203828111612dbb579050905081555060116060516020525f5260405f208054604435808201828110612dbb57905090508155506060516040517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60443560805260206080a3600160805260206080f3611765565b6377917072811861033b57602436103417612dbb576004358060a01c612dbb5760405260066040516020525f5260405f205460605260206060f35b634c01b790811861176557604436103417612dbb576004358060a01c612dbb576040526024356013336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f3611765565b63171ef0b281186103d85734612dbb5760075460405260206040f35b63648c587481186103f45734612dbb5760105460405260206040f35b634b3fd148811861176557604436103417612dbb576024358060a01c612dbb5761034052336103605261118956611765565b633f0bc5bc811861044e5734612dbb57600854604052600954606052600a5460805260606040f35b6316552732811861046a5734612dbb57600f5460405260206040f35b6307a2d13a811861176557602436103417612dbb57602060043560405261049160c0611cd6565b60c0f3611765565b6363eded9581186117655734612dbb57600b54604052600c5460605260406040f3611765565b63c45a015581186117655734612dbb576020612e9360403960206040f3611765565b635c975abb81186117655734612dbb57600d5460405260206040f3611765565b63aba024f481186117655734612dbb57600e5460405260206040f3611765565b6370a08231811861055c57602436103417612dbb576004358060a01c612dbb5760405260116040516020525f5260405f205460605260206060f35b63b6b55f25811861176557602436103417612dbb57336101c05261096a56611765565b6318160ddd811861059b5734612dbb5760025460405260206040f35b63ef8b30f7811861176557602436103417612dbb5760206004356040526105c260a0611d3c565b60a0f3611765565b63dd62ed3e811861176557604436103417612dbb576004358060a01c612dbb576040526024358060a01c612dbb5760605260126040516020525f5260405f20806060516020525f5260405f2090505460805260206080f3611765565b6395d89b4181186106a45734612dbb5760208060805260036040527f434c50000000000000000000000000000000000000000000000000000000000060605260408160800181518152602082015160208201528051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b63ce96cb77811861176557602436103417612dbb576004358060a01c612dbb5760c052601160c0516020525f5260405f20546040526106e360e0611cd6565b60e0516020612e535f395f516370a082316101005230610120526020610100602461011c845afa610716573d5f5f3e3d5ffd5b60203d10612dbb5761010090505180828118828410021890509050610140526020610140f3611765565b63313ce56781186117655734612dbb57601260405260206040f3611765565b63a9059cbb811861176557604436103417612dbb576004358060a01c612dbb576040526011336020525f5260405f208054602435808203828111612dbb579050905081555060116040516020525f5260405f208054602435808201828110612dbb5790509050815550604051337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60243560605260206060a3600160605260206060f3611765565b63095ea7b3811861176557604436103417612dbb576004358060a01c612dbb576040526024356012336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f3611765565b6301e1d11481186117655734612dbb57600154604052600354606052606051604051808201828110612dbb579050905060805260206080f3611765565b63c6e6f592811861176557602436103417612dbb5760206004356040526108ec60a0611d3c565b60a0f3611765565b63402d267d811861176557602436103417612dbb576004358060a01c612dbb576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f3611765565b636e553f6581186109d457604436103417612dbb576024358060a01c612dbb576101c0525b610972611d9c565b6101c05160405260043560605261098a610200611e01565b610200516101e0526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7600435610200526101e051610220526040610200a360206101e0f35b63b3d7f6b9811861176557602436103417612dbb5760206004356040526109fb60c0611cd6565b60c0f3611765565b63c63d75b68118610a5057602436103417612dbb576004358060a01c612dbb576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63c5ebeaec8118610a7457602436103417612dbb5733610340523361036052611189565b635ec8ede4811861176557602436103417612dbb576020612e935f395f513318612dbb57620f424060043511612dbb5760043560105500611765565b63a0712d688118610acf57602436103417612dbb57336101c052610b25565b62f714ce811861176557604436103417612dbb576024358060a01c612dbb57610320523361034052610d2856611765565b6394bf804d8118610baa57604436103417612dbb576024358060a01c612dbb576101c0525b610b2d611d9c565b600435604052610b3e610200611cd6565b610200516101e0526101c0516040526101e051606052610b5f610220611e01565b61022051610200526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d76101e0516102205261020051610240526040610220a360206101e0f35b6314fa10e1811861176557604436103417612dbb576004358060a01c612dbb5761032052610bd6612440565b61032051604052602435606052610beb61271f565b00611765565b630a28a477811861176557602436103417612dbb57600435604052610c1660a0611d3c565b60a0516020612e535f395f516370a0823160c0523060e052602060c0602460dc845afa610c45573d5f5f3e3d5ffd5b60203d10612dbb5760c0905051604052610c60610100611d3c565b6101005180828118828410021890509050610120526020610120f3611765565b632e1a7d4d8118610ca457602436103417612dbb5733610320523361034052610d28565b638456cb5981186117655734612dbb576020612e935f395f513318612dbb576001600d55427f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e5f6040a200611765565b63b460af948118610db757606436103417612dbb576024358060a01c612dbb57610320526044358060a01c612dbb57610340525b610d30612440565b600435604052610d41610380611d3c565b6103805161036052610320516040526103405160605261036051608052610d696103a061249f565b6103a051610380526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db6004356103a052610360516103c05260406103a0a46020610360f35b634cdad506811861176557602436103417612dbb57600435604052610ddc60c0611cd6565b60c0516020612e535f395f516370a0823160e0523061010052602060e0602460fc845afa610e0c573d5f5f3e3d5ffd5b60203d10612dbb5760e0905051604052610e27610120611d3c565b6101205180828118828410021890509050610140526020610140f3611765565b63d905777e811861176557602436103417612dbb576004358060a01c612dbb5760a052601160a0516020525f5260405f20546020612e535f395f516370a0823160c0523060e052602060c0602460dc845afa610ea5573d5f5f3e3d5ffd5b60203d10612dbb5760c0905051604052610ec0610100611d3c565b6101005180828118828410021890509050610120526020610120f3611765565b63db006a758118610f0457602436103417612dbb5733610320523361034052611080565b63b5effcf3811861176557604436103417612dbb576004358060a01c612dbb5761032052610f30612440565b61032051604052602435606052610f45612812565b336101c0526007546101e052610f5c610340612cd8565b61034051610fc9576017610360527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103805261036050610360518061038001601f825f031636823750506308c379a061032052602061034052601f19601f61036051011660440161033cfd5b00611765565b637bde82f28118610ffd57604436103417612dbb576024358060a01c612dbb57610320523361034052611080565b633f4ba83a81186117655734612dbb576020612e935f395f513318612dbb575f600d55427fb96cc4c95dd57612feeeaed56e65b2fd6ba67b101d0592527f05756fafcab4b45f6040a200611765565b63ba087652811861176557606436103417612dbb576024358060a01c612dbb57610320526044358060a01c612dbb57610340525b611088612440565b61032051604052610340516060526004356080526110a761038061249f565b61038051610360526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db61036051610380526004356103a0526040610380a46020610360f3611765565b6332874ec7811861176557604436103417612dbb576004358060a01c612dbb576040526024358060a01c612dbb5760605260136040516020525f5260405f20806060516020525f5260405f2090505460805260206080f3611765565b63d516418481186112ac57606436103417612dbb576024358060a01c612dbb57610340526044358060a01c612dbb57610360525b611191611d9c565b611199612440565b3361034051146111d6576013610340516020525f5260405f2080336020525f5260405f2090508054600435808203828111612dbb57905090508155505b6004356101a052610340516101c052610360516101e0526111f86103a061297e565b6103a05161038052610340516101c0526007546101e05261121a6103a0612cd8565b6103a0516112875760176103c0527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103e0526103c0506103c051806103e001601f825f031636823750506308c379a06103805260206103a052601f19601f6103c051011660440161039cfd5b600854604052600954606052600a546080525f60a0526112a5611f9f565b6020610380f35b631c12948e81186117655734612dbb576020612e935f395f516326cfa27c606052602060606004607c845afa6112e4573d5f5f3e3d5ffd5b60203d10612dbb576060518060a01c612dbb5760a05260a0905051604052600854606052600954608052600a5460a05260a05160c05260116040516020525f5260405f205460c051808201828110612dbb579050905060116040516020525f5260405f20555f600a556040515f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60c05160e052602060e0a300611765565b63371fd8e6811861176557602436103417612dbb576113a0612440565b60206004356101e0526113b4610320612baa565b610320f3611765565b634914c008811861176557606436103417612dbb576004358060a01c612dbb57610320526044358060a01c612dbb5761034052604036610360376114026103a06128f7565b6103a08051610380526020810151610360525061141d612440565b6060366103a0376003546104005260045461042052610320516101c052610360516101e05261144d610440612cd8565b6104405161158d576006610320516020525f5260405f20546104605260243561046051808281188284100218905090506103e052610460516103e051808203828111612dbb57905090506006610320516020525f5260405f205561040051604052610420516060526103e0516080525f60a0526114cb6104806117fc565b610480516103c0526103c0516201b5808102816201b580820418612dbb57905061036051808202811583838304141715612dbb579050905069152d02c7e14af6800000810490506103a0526005610320516020525f5260405f20546103a05111611535575f611540565b610460516103e05118155b1561155a576005610320516020525f5260405f20546103a0525b6005610320516020525f5260405f20546103a051808203828111612dbb57905090506005610320516020525f5260405f20555b6103c0516115fa576018610440527f436f67506169723a205573657220697320736f6c76656e7400000000000000006104605261044050610440518061046001601f825f031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b6003546103c0518060801c612dbb578082038060801c612dbb57905090506003556004546103e0518060801c612dbb578082038060801c612dbb57905090506004555f546103a051808203828111612dbb57905090505f556020612e735f395f5163a9059cbb6104405261034051610460526103a051610480526020610440604461045c5f855af161168e573d5f5f3e3d5ffd5b3d6116a557803b15612dbb5760016104a0526116be565b60203d10612dbb57610440518060011c612dbb576104a0525b6104a090505115612dbb576020612e535f395f516323b872dd61044052336104605230610480526103c0516104a0526020610440606461045c5f855af1611707573d5f5f3e3d5ffd5b3d61171e57803b15612dbb5760016104c052611737565b60203d10612dbb57610440518060011c612dbb576104c0525b6104c090505115612dbb576001546103c0518060801c612dbb578082018060801c612dbb5790509050600155005b5f5ffd5b60405161177f576080518152506117fa566117fa565b608051606051808202811583838304141715612dbb57905090506040518015612dbb578082049050905060a05260805160a051604051808202811583838304141715612dbb57905090506060518015612dbb578082049050905010156117f35760a05160018101818110612dbb57905060a0525b60a0518152505b565b6060516118125760805181525061189b5661189b565b608051604051808202811583838304141715612dbb57905090506060518015612dbb578082049050905060c05260a05161184c575f61187b565b60805160c051606051808202811583838304141715612dbb57905090506040518015612dbb5780820490509050105b156118945760c05160018101818110612dbb57905060c0525b60c0518152505b565b60c0516101205260e051610140526101205160405261014051606052610100516080526118cb610180611769565b610180516101605261012051610100518060801c612dbb578082018060801c612dbb57905090506101205261014051610160518060801c612dbb578082018060801c612dbb57905090506101405261012051815261014051602082015261016051604082015250565b60e0516101605261010051610180526101605160405261018051606052610120516080526101405160a05261196a6101c06117fc565b6101c0516101a052610160516101a0518060801c612dbb578082038060801c612dbb57905090506101605261018051610120518060801c612dbb578082038060801c612dbb5790509050610180526101605181526101805160208201526101a051604082015250565b608051611a3657601e60c0527f4d6174683a206d756c5f646976206469766973696f6e206279207a65726f000060e05260c05060c0518060e001601f825f031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b6040516060517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8183099050905060c0526060516040510260e0525f6101005260e05160c05110611a915760e05160c0510361010052611aa0565b600160e05160c0510303610100525b61010051611afa5760a051611ab5575f611ad1565b6040516060516080518015612dbb578082840990509050905015155b611ae85760805160e05104815250611cd456611afa565b600160805160e0510401815250611cd4565b6101005160805111611b69576016610120527f4d6174683a206d756c5f646976206f766572666c6f77000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6040516060516080518015612dbb57808284099050905090506101205260e051610120511115611b9f5760016101005103610100525b6101205160e0510360e0526080516080515f0316610140526101405160805104610160526101405160e0510460e052600161014051610140515f0304016101405261014051610100510260e0511760e05260026101605160030218610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805160e051026101a05260a051611c95575f611cb1565b6040516060516080518015612dbb578082840990509050905015155b15611ccc576101a05160018101818110612dbb5790506101a0525b6101a0518152505b565b600154606052600254608052608051611cf457604051815250611d3a565b6060516003548082018060801c612dbb579050905060a05260405160a051808202811583838304141715612dbb57905090506080518015612dbb57808204905090508152505b565b6002546060526001546003548082018060801c612dbb5790509050608052608051611d6c57604051815250611d9a565b604051606051808202811583838304141715612dbb57905090506080518015612dbb57808204905090508152505b565b600d5415611dff57600b6040527f506169722050617573656400000000000000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b565b60015460805260025460a0526080516003548082018060801c612dbb579050905060c0525f60e05260c051611e3b5760605160e052611e69565b60605160a051808202811583838304141715612dbb579050905060c0518015612dbb578082049050905060e0525b6103e760a05160e0518060801c612dbb578082018060801c612dbb579050905013611e97575f815250611f9d565b6001546060518060801c612dbb578082018060801c612dbb57905090506101005260025460e0518060801c612dbb578082018060801c612dbb579050905061012052610100516001556101205160025560116040516020525f5260405f205460e051808201828110612dbb5790509050610100526101005160116040516020525f5260405f20556020612e535f395f516323b872dd6101205233610140523061016052606051610180526020610120606461013c5f855af1611f5b573d5f5f3e3d5ffd5b3d611f7257803b15612dbb5760016101a052611f8b565b60203d10612dbb57610120518060011c612dbb576101a0525b6101a090505115612dbb5760e0518152505b565b60405160c05260605160e05260805161010052428060401c612dbb5760e052600354610120526004546101405261014051612006576020612ef35f395f5160c05114611fee576020612ef360c0395b60c05160085560e05160095561010051600a5561243e565b604036610160376001546101a0526002546101c0526101205160c051808202811583838304141715612dbb579050905060a051808202811583838304141715612dbb5790509050670de0b6b3a7640000810490506101605261012051610160518060801c612dbb578082018060801c612dbb5790509050610120526101a05161012051808201828110612dbb57905090506101e05261016051600f54808202811583838304141715612dbb5790509050620f42408104905061020052610200516101c051808202811583838304141715612dbb57905090506101e0518015612dbb57808204905090506101805261010051610180518060801c612dbb578082018060801c612dbb5790509050610100526101c051610180518060801c612dbb578082018060801c612dbb5790509050600255610120516003556101405160045561012051670de0b6b3a7640000810281670de0b6b3a7640000820418612dbb5790506101e0518015612dbb5780820490509050610220526020612eb35f395f5161022051106122a7576020612ed35f395f516102205111156123a757610220516020612ed35f395f51808203828111612dbb5790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612dbb5790506020612ed35f395f518015612dbb5780820490509050610240526020612f535f395f516102405161024051808202811583838304141715612dbb579050905060a051808202811583838304141715612dbb5790509050808201828110612dbb57905090506102605260c05161026051808202811583838304141715612dbb57905090506020612f535f395f518015612dbb57808204905090508060401c612dbb57610280526102805160c0526020612f335f395f516102805113156123a7576020612f3360c0396123a7565b6020612eb35f395f5161022051808203828111612dbb5790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612dbb5790506020612eb35f395f518015612dbb5780820490509050610240526020612f535f395f516102405161024051808202811583838304141715612dbb579050905060a051808202811583838304141715612dbb5790509050808201828110612dbb57905090506102605260c0516020612f535f395f51808202811583838304141715612dbb5790509050610260518015612dbb57808204905090508060401c612dbb57610280526102805160c0526020612f135f395f5160c05112156123a7576020612f1360c0395b428060401c612dbb57600c548082038060401c612dbb5790509050610240526203f481610240511261242a57600b5460c051136123e957601054600f5561242a565b60c051600b548082038060401c612dbb5790509050610260526361830fc1610260511261242a57428060401c612dbb57600c5560c051600b55620f4240600f555b60c05160085560e05160095561010051600a555b565b6008546102a0526009546102c052600a546102e052426102c051808203828111612dbb579050905061030052610300516124795761249d565b6102a0516040526102c0516060526102e0516080526103005160a05261249d611f9f565b565b336060511461255b5760805160126060516020525f5260405f2080336020525f5260405f20905054101561252957601660a0527f496e73756666696369656e7420416c6c6f77616e63650000000000000000000060c05260a05060a0518060c001601f825f031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b60126060516020525f5260405f2080336020525f5260405f2090508054608051808203828111612dbb57905090508155505b60015460a05260025460c05260a0516003548082018060801c612dbb579050905060e05260805160e051808202811583838304141715612dbb579050905060c0518015612dbb57808204905090506101005260a051610100518060801c612dbb578082038060801c612dbb579050905060a05260c0516080518060801c612dbb578082038060801c612dbb579050905060c0526103e860c051121561265d57600d610120527f42656c6f77204d696e696d756d000000000000000000000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60a05160015560c05160025560116060516020525f5260405f2054608051808203828111612dbb5790509050610120526101205160116060516020525f5260405f20556020612e535f395f5163a9059cbb610140526040516101605261010051610180526020610140604461015c5f855af16126db573d5f5f3e3d5ffd5b3d6126f257803b15612dbb5760016101a05261270b565b60203d10612dbb57610140518060011c612dbb576101a0525b6101a090505115612dbb5761010051815250565b60056040516020525f5260405f2054606051808201828110612dbb579050905060805260805160056040516020525f5260405f20555f5460a05260a051606051808201828110612dbb57905090505f556020612e735f395f516323b872dd60c0523360e052306101005260605161012052602060c0606460dc5f855af16127a8573d5f5f3e3d5ffd5b3d6127bf57803b15612dbb576001610140526127d7565b60203d10612dbb5760c0518060011c612dbb57610140525b61014090505115612dbb576080516060516040517fe3f4fa74d049cf7d64965afd6ce83c826cd313cec824ecfb9aacf36886090b495f60c0a4565b6005336020525f5260405f2054606051808203828111612dbb57905090506080526080516005336020525f5260405f20555f54606051808203828111612dbb57905090505f556020612e735f395f5163a9059cbb60a05260405160c05260605160e052602060a0604460bc5f855af161288d573d5f5f3e3d5ffd5b3d6128a457803b15612dbb576001610100526128bc565b60203d10612dbb5760a0518060011c612dbb57610100525b61010090505115612dbb576080516060516040517fdec5d726a70bdc7ab7e167507e34e068ab89db504d9ddcb08618c73a1f10a93e5f60a0a4565b6040366040376020612e335f395f51636d4ce63c608052604060806004609c5f855af1612926573d5f5f3e3d5ffd5b60403d10612dbb576080518060011c612dbb5760e05260a0516101005260e0905080516040526020810151606052506040516129675760075460605261296e565b6060516007555b6040518152606051602082015250565b6129896102006128f7565b610200506101a051600e54808202811583838304141715612dbb5790509050620186a081049050610200526060366102203760035460c05260045460e0526101a05161020051808201828110612dbb5790509050610100526129ec61028061189d565b61028080516102205260208101516102405260408101516102605250610220516003556102405160045560066101c0516020525f5260405f205461026051808201828110612dbb579050905060066101c0516020525f5260405f2055600154610280526002546102a0526103e86102a0511215612ac857600d6102c0527f42656c6f77204d696e696d756d000000000000000000000000000000000000006102e0526102c0506102c051806102e001601f825f031636823750506308c379a06102805260206102a052601f19601f6102c051011660440161029cfd5b610280516101a051808203828111612dbb57905090508060801c612dbb5761028052610280516001556102a0516002556020612e535f395f5163a9059cbb6102c0526101e0516102e0526101a0516103005260206102c060446102dc5f855af1612b34573d5f5f3e3d5ffd5b3d612b4b57803b15612dbb57600161032052612b64565b60203d10612dbb576102c0518060011c612dbb57610320525b61032090505115612dbb576101c0516101e0516101a0517f322a69e46c4e1be12df82297341b3c5651c9f47519342541b412514bed8aac895f6102c0a46101a051815250565b6060366102003760035460e052600454610100526101e05161012052600161014052612bd7610260611934565b6102608051610200526020810151610220526040810151610240525061020051600355610220516004556006336020525f5260405f20546101e051808203828111612dbb57905090506006336020525f5260405f2055600154610260526020612e535f395f516323b872dd61028052336102a052306102c052610240516102e0526020610280606461029c5f855af1612c72573d5f5f3e3d5ffd5b3d612c8957803b15612dbb57600161030052612ca2565b60203d10612dbb57610280518060011c612dbb57610300525b61030090505115612dbb5761026051610240518060801c612dbb578082018060801c612dbb579050905060015561024051815250565b60066101c0516020525f5260405f20546102005261020051612cfe576001815250612db9565b60056101c0516020525f5260405f20546102205261022051612d23575f815250612db9565b6003546102405260045461026052610220516509184e72a0008102816509184e72a000820418612dbb57905062014c0881028162014c08820418612dbb579050610280526102005161024051808202811583838304141715612dbb57905090506040526101e051606052610260516080525f60a052612da36102a06119d3565b6102a05161020052610200516102805110158152505b565b5f80fd17651765050101b40fcf018e11550c8017650b00138317651765052103bc04bf1765074008c51765030001da13bd0ee00cf404991765176517651765176500931765176505ca0bf10a0310f9088817651765075f04260626014d04e10ab00807104c08f4176509450e47003a0018057f17651765000000000000000000000000480501d16841181d267a3a40b5b1f0126473ab310000000000000000000000005300000000000000000000000000000000000004000000000000000000000000a25b25548b4c98b0c7d3d27dca5d5ca743d68b7f000000000000000000000000cd44fecb08bb28405992358131fd5081a0f550d000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000009b6e64a8ec60000000000000000000000000000000000000000000000000000000000005e80a6c00000000000000000000000000000000000000000000000000000000025cd0f80000000000000000000000000000000000000000000000000000000023703e88000000000000000000000000000000054a2b63d65d79d094abb66880000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005300000000000000000000000000000000000004000000000000000000000000a25b25548b4c98b0c7d3d27dca5d5ca743d68b7f000000000000000000000000480501d16841181d267a3a40b5b1f0126473ab3100000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000009b6e64a8ec60000000000000000000000000000000000000000000000000000000000005e80a6c00000000000000000000000000000000000000000000000000000000025cd0f80000000000000000000000000000000000000000000000000000000023703e88000000000000000000000000000000054a2b63d65d79d094abb66880000000000
-----Decoded View---------------
Arg [0] : _asset (address): 0x5300000000000000000000000000000000000004
Arg [1] : _collateral (address): 0xa25b25548B4C98B0c7d3d27dcA5D5ca743d68b7F
Arg [2] : _oracle (address): 0x480501d16841181d267A3a40B5B1f0126473AB31
Arg [3] : min_target_utilization (uint256): 500000000000000000
Arg [4] : max_target_utilization (uint256): 700000000000000000
Arg [5] : starting_interest_per_second (uint64): 1585489600
Arg [6] : min_interest (uint64): 634195840
Arg [7] : max_interest (uint64): 9512937600
Arg [8] : elasticity (uint256): 28800000000000000000000000000000000000000
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000005300000000000000000000000000000000000004
Arg [1] : 000000000000000000000000a25b25548b4c98b0c7d3d27dca5d5ca743d68b7f
Arg [2] : 000000000000000000000000480501d16841181d267a3a40b5b1f0126473ab31
Arg [3] : 00000000000000000000000000000000000000000000000006f05b59d3b20000
Arg [4] : 00000000000000000000000000000000000000000000000009b6e64a8ec60000
Arg [5] : 000000000000000000000000000000000000000000000000000000005e80a6c0
Arg [6] : 0000000000000000000000000000000000000000000000000000000025cd0f80
Arg [7] : 000000000000000000000000000000000000000000000000000000023703e880
Arg [8] : 00000000000000000000000000000054a2b63d65d79d094abb66880000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$19,237.76
Net Worth in ETH
Token Allocations
WETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| SCROLL | 100.00% | $2,959.82 | 6.4996 | $19,237.76 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.