Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 31,818 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Liquidate | 25562439 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562438 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562437 | 58 days ago | IN | 0 ETH | 0.00000003 | ||||
| Liquidate | 25562436 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562435 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562433 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562432 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562421 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562419 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562418 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562417 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562416 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562415 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25562413 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25561901 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25561900 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25561899 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25561897 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25561896 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25561895 | 58 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25508452 | 59 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25508319 | 59 days ago | IN | 0 ETH | 0.00000004 | ||||
| Liquidate | 25508282 | 59 days ago | IN | 0 ETH | 0.00000004 | ||||
| Withdraw | 16192078 | 236 days ago | IN | 0 ETH | 0.00000214 | ||||
| Withdraw | 15311668 | 261 days ago | IN | 0 ETH | 0.00000125 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 121873 | 829 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.9
Contract Source Code (Vyper language format)
# @version 0.3.9
"""
@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) = 75000 # 75%
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(to: address, payment: uint256) -> uint256:
"""
@param to: The address to repay the tokens for
@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[to] = self.user_borrow_part[to] - 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(to: address, payment: uint256) -> uint256:
"""
@param to The address to repay the tokens for
@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(to, 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_part, 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":"to","type":"address"},{"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
612db151506020612dfb5f395f518060a01c612df7576040526020612e1b5f395f518060a01c612df7576060526020612e3b5f395f518060a01c612df7576080526020612e9b5f395f518060401c612df75760a0526020612ebb5f395f518060401c612df75760c0526020612edb5f395f518060401c612df75760e05234612df7576060516100ea576012610100527f496e76616c696420436f6c6c61746572616c00000000000000000000000000006101205261010050610100518061012001601f825f031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b606051612cd152604051612cb152608051612c9152620186a0601055620186a0600f556020612e5b5f395f51612d11526020612e7b5f395f51612d315260a051612d515260c051612d715260e051612d91526020612efb5f395f51612db1526032600e5533612cf152612c9161016561000039612dd1610000f36003361161000c5761163c565b5f3560e01c34612c8057637dc0d1d08118610033576020612c915f395f5160405260206040f35b6338d52e0f8118610050576020612cb15f395f5160405260206040f35b63d8dfeb45811861006d576020612cd15f395f5160405260206040f35b631ac0e2928118610083575f5460405260206040f35b636b8833c981186100a05760015460405260025460605260406040f35b638274109781186100bd5760035460405260045460605260406040f35b632b5fca1d81186100f65760243610612c80576004358060a01c612c805760405260056040516020525f5260405f205460605260206060f35b6377917072811861012f5760243610612c80576004358060a01c612c805760405260066040516020525f5260405f205460605260206060f35b63171ef0b281186101465760075460405260206040f35b633f0bc5bc811861016957600854604052600954606052600a5460805260606040f35b6363eded95811861018657600b54604052600c5460605260406040f35b63c45a015581186101a3576020612cf15f395f5160405260206040f35b635c975abb81186101ba57600d5460405260206040f35b63aba024f481186101d157600e5460405260206040f35b631655273281186101e857600f5460405260206040f35b63648c587481186101ff5760105460405260206040f35b6370a0823181186102385760243610612c80576004358060a01c612c805760405260116040516020525f5260405f205460605260206060f35b6318160ddd811861024f5760025460405260206040f35b63dd62ed3e81186102a55760443610612c80576004358060a01c612c80576040526024358060a01c612c805760605260126040516020525f5260405f20806060516020525f5260405f2090505460805260206080f35b6306fdde0381186103245760208060805260116040527f436f6720506f6f6c204c5020546f6b656e00000000000000000000000000000060605260408160800181516020830160208301815181525050808252508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b6395d89b4181186103a35760208060805260036040527f434c50000000000000000000000000000000000000000000000000000000000060605260408160800181516020830160208301815181525050808252508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b63313ce56781186103b957601260405260206040f35b63a9059cbb811861045b5760443610612c80576004358060a01c612c80576040526011336020525f5260405f208054602435808203828111612c80579050905081555060116040516020525f5260405f208054602435808201828110612c805790509050815550604051337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60243560605260206060a3600160605260206060f35b63095ea7b381186104d65760443610612c80576004358060a01c612c80576040526024356012336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f35b6323b872dd81186105bb5760643610612c80576004358060a01c612c80576040526024358060a01c612c805760605260126040516020525f5260405f2080336020525f5260405f2090508054604435808203828111612c80579050905081555060116040516020525f5260405f208054604435808203828111612c80579050905081555060116060516020525f5260405f208054604435808201828110612c8057905090508155506060516040517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60443560805260206080a3600160805260206080f35b6301e1d11481186105ef57600154604052600354606052606051604051808201828110612c80579050905060805260206080f35b6307a2d13a81186106185760243610612c8057602060043560405261061460c0611b89565b60c0f35b63c6e6f59281186106415760243610612c8057602060043560405261063d60a0611bef565b60a0f35b63402d267d811861068c5760243610612c80576004358060a01c612c80576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63ef8b30f781186106b55760243610612c805760206004356040526106b160a0611bef565b60a0f35b63b6b55f2581186106d25760243610612c8057336101c0526106f5565b636e553f65811861075f5760443610612c80576024358060a01c612c80576101c0525b6106fd611c4f565b6101c051604052600435606052610715610200611cb4565b610200516101e0526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7600435610200526101e051610220526040610200a360206101e0f35b63c63d75b681186107aa5760243610612c80576004358060a01c612c80576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63b3d7f6b981186107d35760243610612c805760206004356040526107cf60c0611b89565b60c0f35b63a0712d6881186107f05760243610612c8057336101c052610813565b6394bf804d81186108985760443610612c80576024358060a01c612c80576101c0525b61081b611c4f565b60043560405261082c610200611b89565b610200516101e0526101c0516040526101e05160605261084d610220611cb4565b61022051610200526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d76101e0516102205261020051610240526040610220a360206101e0f35b63ce96cb77811861092e5760243610612c80576004358060a01c612c805760c052601160c0516020525f5260405f20546040526108d560e0611b89565b60e0516020612cb15f395f516370a082316101005230610120526020610100602461011c845afa610908573d5f5f3e3d5ffd5b60203d10612c805761010090505180828118828410021890509050610140526020610140f35b630a28a47781186109b75760243610612c805760043560405261095160a0611bef565b60a0516020612cb15f395f516370a0823160c0523060e052602060c0602460dc845afa610980573d5f5f3e3d5ffd5b60203d10612c805760c090505160405261099b610100611bef565b6101005180828118828410021890509050610120526020610120f35b632e1a7d4d81186109d95760243610612c805733610320523361034052610a36565b62f714ce8118610a045760443610612c80576024358060a01c612c8057610320523361034052610a36565b63b460af948118610ac55760643610612c80576024358060a01c612c8057610320526044358060a01c612c8057610340525b610a3e6122ff565b600435604052610a4f610380611bef565b6103805161036052610320516040526103405160605261036051608052610a776103a061235e565b6103a051610380526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db6004356103a052610360516103c05260406103a0a46020610360f35b63d905777e8118610b585760243610612c80576004358060a01c612c805760a052601160a0516020525f5260405f20546020612cb15f395f516370a0823160c0523060e052602060c0602460dc845afa610b21573d5f5f3e3d5ffd5b60203d10612c805760c0905051604052610b3c610100611bef565b6101005180828118828410021890509050610120526020610120f35b634cdad5068118610be25760243610612c8057600435604052610b7b60c0611b89565b60c0516020612cb15f395f516370a0823160e0523061010052602060e0602460fc845afa610bab573d5f5f3e3d5ffd5b60203d10612c805760e0905051604052610bc6610120611bef565b6101205180828118828410021890509050610140526020610140f35b63db006a758118610c045760243610612c805733610320523361034052610c62565b637bde82f28118610c305760443610612c80576024358060a01c612c8057610320523361034052610c62565b63ba0876528118610cd75760643610612c80576024358060a01c612c8057610320526044358060a01c612c8057610340525b610c6a6122ff565b6103205160405261034051606052600435608052610c8961038061235e565b61038051610360526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db61036051610380526004356103a0526040610380a46020610360f35b63f8ba4cff8118610cec57610cea6122ff565b005b6314fa10e18118610d2d5760443610612c80576004358060a01c612c805761032052610d166122ff565b61032051604052602435606052610d2b6125de565b005b63b5effcf38118610df25760443610612c80576004358060a01c612c805761032052610d576122ff565b61032051604052602435606052610d6c6126d1565b336101c0526007546101e052610d83610340612b9d565b61034051610df0576017610360527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103805261036050610360518061038001601f825f031636823750506308c379a061032052602061034052601f19601f61036051011660440161033cfd5b005b6332874ec78118610e485760443610612c80576004358060a01c612c80576040526024358060a01c612c805760605260136040516020525f5260405f20806060516020525f5260405f2090505460805260206080f35b634c01b7908118610ec35760443610612c80576004358060a01c612c80576040526024356013336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f35b63c5ebeaec8118610ee55760243610612c805733610340523361036052610f43565b634b3fd1488118610f115760443610612c80576024358060a01c612c8057610340523361036052610f43565b63d516418481186110665760643610612c80576024358060a01c612c8057610340526044358060a01c612c8057610360525b610f4b611c4f565b610f536122ff565b336103405114610f90576013610340516020525f5260405f2080336020525f5260405f2090508054600435808203828111612c8057905090508155505b6004356101a052610340516101c052610360516101e052610fb26103a061283d565b6103a05161038052610340516101c0526007546101e052610fd46103a0612b9d565b6103a0516110415760176103c0527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103e0526103c0506103c051806103e001601f825f031636823750506308c379a06103805260206103a052601f19601f6103c051011660440161039cfd5b600854604052600954606052600a546080525f60a05261105f611e52565b6020610380f35b6322867d7881186110b15760443610612c80576004358060a01c612c8057610340526110906122ff565b6020610340516101e052602435610200526110ac610360612a69565b610360f35b63fe9f6e2481186110ce5760406110c96101206127b6565b610120f35b634914c00881186114745760643610612c80576004358060a01c612c8057610320526044358060a01c612c805761034052604036610360376111116103a06127b6565b6103a08051610380526020810151610360525061112c6122ff565b6060366103a0376003546104005260045461042052610320516101c052610360516101e05261115c610440612b9d565b6104405161129c576006610320516020525f5260405f20546104605260243561046051808281188284100218905090506103e052610460516103e051808203828111612c8057905090506006610320516020525f5260405f205561040051604052610420516060526103e0516080525f60a0526111da6104806116cf565b610480516103c0526103c0516201b5808102816201b580820418612c8057905061036051808202811583838304141715612c80579050905069152d02c7e14af6800000810490506103a0526005610320516020525f5260405f20546103a05111611244575f61124f565b610460516103e05118155b15611269576005610320516020525f5260405f20546103a0525b6005610320516020525f5260405f20546103a051808203828111612c8057905090506005610320516020525f5260405f20555b6103c051611309576018610440527f436f67506169723a205573657220697320736f6c76656e7400000000000000006104605261044050610440518061046001601f825f031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b6003546103c0518060801c612c80578082038060801c612c8057905090506003556004546103e0518060801c612c80578082038060801c612c8057905090506004555f546103a051808203828111612c8057905090505f556020612cd15f395f5163a9059cbb6104405261034051610460526103a051610480526020610440604461045c5f855af161139d573d5f5f3e3d5ffd5b3d6113b457803b15612c805760016104a0526113cd565b60203d10612c8057610440518060011c612c80576104a0525b6104a090505115612c80576020612cb15f395f516323b872dd61044052336104605230610480526103c0516104a0526020610440606461045c5f855af1611416573d5f5f3e3d5ffd5b3d61142d57803b15612c805760016104c052611446565b60203d10612c8057610440518060011c612c80576104c0525b6104c090505115612c80576001546103e0518060801c612c80578082018060801c612c805790509050600155005b63dba2d55381186114a95760243610612c80576020612cf15f395f513318612c805761c35060043511612c8057600435600e55005b635ec8ede481186114df5760243610612c80576020612cf15f395f513318612c8057620f424060043511612c8057600435601055005b638456cb598118611526576020612cf15f395f513318612c80576001600d55427f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e5f6040a2005b633f4ba83a811861156c576020612cf15f395f513318612c80575f600d55427fb96cc4c95dd57612feeeaed56e65b2fd6ba67b101d0592527f05756fafcab4b45f6040a2005b631c12948e811861163a576020612cf15f395f516326cfa27c606052602060606004607c845afa61159f573d5f5f3e3d5ffd5b60203d10612c80576060518060a01c612c805760a05260a0905051604052600854606052600954608052600a5460a05260a05160c05260116040516020525f5260405f205460c051808201828110612c80579050905060116040516020525f5260405f20555f600a556040515f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60c05160e052602060e0a3005b505b5f5ffd5b604051611652576080518152506116cd565b608051606051808202811583838304141715612c8057905090506040518015612c80578082049050905060a05260805160a051604051808202811583838304141715612c8057905090506060518015612c80578082049050905010156116c65760a05160018101818110612c8057905060a0525b60a0518152505b565b6060516116e15760805181525061176a565b608051604051808202811583838304141715612c8057905090506060518015612c80578082049050905060c05260a05161171b575f61174a565b60805160c051606051808202811583838304141715612c8057905090506040518015612c805780820490509050105b156117635760c05160018101818110612c8057905060c0525b60c0518152505b565b60c0516101205260e0516101405261012051604052610140516060526101005160805261179a610180611640565b610180516101605261012051610100518060801c612c80578082018060801c612c8057905090506101205261014051610160518060801c612c80578082018060801c612c8057905090506101405261012051815261014051602082015261016051604082015250565b60e0516101605261010051610180526101605160405261018051606052610120516080526101405160a0526118396101c06116cf565b6101c0516101a052610160516101a0518060801c612c80578082038060801c612c8057905090506101605261018051610120518060801c612c80578082038060801c612c805790509050610180526101605181526101805160208201526101a051604082015250565b60805161190557601e60c0527f4d6174683a206d756c5f646976206469766973696f6e206279207a65726f000060e05260c05060c0518060e001601f825f031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6060516040510960c0526060516040510260e0525f6101005260e05160c0511061195a5760e05160c0510361010052611969565b600160e05160c0510303610100525b610100516119b95760a05161197e575f611994565b6080518015612c80578060605160405109905015155b6119a75760805160e05104815250611b87565b600160805160e0510401815250611b87565b6101005160805111611a28576016610120527f4d6174683a206d756c5f646976206f766572666c6f77000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6080518015612c8057806060516040510990506101205260e051610120511115611a585760016101005103610100525b6101205160e0510360e0526080516080515f0316610140526101405160805104610160526101405160e0510460e052600161014051610140515f0304016101405261014051610100510260e0511760e05260026101605160030218610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805160e051026101a05260a051611b4e575f611b64565b6080518015612c80578060605160405109905015155b15611b7f576101a05160018101818110612c805790506101a0525b6101a0518152505b565b600154606052600254608052608051611ba757604051815250611bed565b6060516003548082018060801c612c80579050905060a05260405160a051808202811583838304141715612c8057905090506080518015612c8057808204905090508152505b565b6002546060526001546003548082018060801c612c805790509050608052608051611c1f57604051815250611c4d565b604051606051808202811583838304141715612c8057905090506080518015612c8057808204905090508152505b565b600d5415611cb257600b6040527f506169722050617573656400000000000000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b565b60015460805260025460a0526080516003548082018060801c612c80579050905060c0525f60e05260c051611cee5760605160e052611d1c565b60605160a051808202811583838304141715612c80579050905060c0518015612c80578082049050905060e0525b6103e760a05160e0518060801c612c80578082018060801c612c80579050905013611d4a575f815250611e50565b6001546060518060801c612c80578082018060801c612c8057905090506101005260025460e0518060801c612c80578082018060801c612c80579050905061012052610100516001556101205160025560116040516020525f5260405f205460e051808201828110612c805790509050610100526101005160116040516020525f5260405f20556020612cb15f395f516323b872dd6101205233610140523061016052606051610180526020610120606461013c5f855af1611e0e573d5f5f3e3d5ffd5b3d611e2557803b15612c805760016101a052611e3e565b60203d10612c8057610120518060011c612c80576101a0525b6101a090505115612c805760e0518152505b565b60405160c05260605160e05260805161010052428060401c612c805760e052600354610120526004546101405261014051611ebd576020612d515f395f5160c05114611ea5576020612d515f395f5160c0525b60c05160085560e05160095561010051600a556122fd565b604036610160376001546101a0526002546101c0526101205160c051808202811583838304141715612c80579050905060a051808202811583838304141715612c805790509050670de0b6b3a7640000810490506101605261012051610160518060801c612c80578082018060801c612c805790509050610120526101a05161012051808201828110612c8057905090506101e05261016051600f54808202811583838304141715612c805790509050620f42408104905061020052610200516101c051808202811583838304141715612c8057905090506101e0518015612c8057808204905090506101805261010051610180518060801c612c80578082018060801c612c805790509050610100526101c051610180518060801c612c80578082018060801c612c805790509050600255610120516003556101405160045561012051670de0b6b3a7640000810281670de0b6b3a7640000820418612c805790506101e0518015612c805780820490509050610220526020612d115f395f516102205110612162576020612d315f395f5161022051111561226657610220516020612d315f395f51808203828111612c805790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612c805790506020612d315f395f518015612c805780820490509050610240526020612db15f395f516102405161024051808202811583838304141715612c80579050905060a051808202811583838304141715612c805790509050808201828110612c8057905090506102605260c05161026051808202811583838304141715612c8057905090506020612db15f395f518015612c8057808204905090508060401c612c8057610280526102805160c0526020612d915f395f51610280511315612266576020612d915f395f5160c052612266565b6020612d115f395f5161022051808203828111612c805790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612c805790506020612d115f395f518015612c805780820490509050610240526020612db15f395f516102405161024051808202811583838304141715612c80579050905060a051808202811583838304141715612c805790509050808201828110612c8057905090506102605260c0516020612db15f395f51808202811583838304141715612c805790509050610260518015612c8057808204905090508060401c612c8057610280526102805160c0526020612d715f395f5160c0511215612266576020612d715f395f5160c0525b428060401c612c8057600c548082038060401c612c805790509050610240526203f48161024051126122e957600b5460c051136122a857601054600f556122e9565b60c051600b548082038060401c612c805790509050610260526361830fc161026051126122e957428060401c612c8057600c5560c051600b55620f4240600f555b60c05160085560e05160095561010051600a555b565b6008546102a0526009546102c052600a546102e052426102c051808203828111612c80579050905061030052610300516123385761235c565b6102a0516040526102c0516060526102e0516080526103005160a05261235c611e52565b565b336060511461241a5760805160126060516020525f5260405f2080336020525f5260405f2090505410156123e857601660a0527f496e73756666696369656e7420416c6c6f77616e63650000000000000000000060c05260a05060a0518060c001601f825f031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b60126060516020525f5260405f2080336020525f5260405f2090508054608051808203828111612c8057905090508155505b60015460a05260025460c05260a0516003548082018060801c612c80579050905060e05260805160e051808202811583838304141715612c80579050905060c0518015612c8057808204905090506101005260a051610100518060801c612c80578082038060801c612c80579050905060a05260c0516080518060801c612c80578082038060801c612c80579050905060c0526103e860c051121561251c57600d610120527f42656c6f77204d696e696d756d000000000000000000000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60a05160015560c05160025560116060516020525f5260405f2054608051808203828111612c805790509050610120526101205160116060516020525f5260405f20556020612cb15f395f5163a9059cbb610140526040516101605261010051610180526020610140604461015c5f855af161259a573d5f5f3e3d5ffd5b3d6125b157803b15612c805760016101a0526125ca565b60203d10612c8057610140518060011c612c80576101a0525b6101a090505115612c805761010051815250565b60056040516020525f5260405f2054606051808201828110612c80579050905060805260805160056040516020525f5260405f20555f5460a05260a051606051808201828110612c8057905090505f556020612cd15f395f516323b872dd60c0523360e052306101005260605161012052602060c0606460dc5f855af1612667573d5f5f3e3d5ffd5b3d61267e57803b15612c8057600161014052612696565b60203d10612c805760c0518060011c612c8057610140525b61014090505115612c80576080516060516040517fe3f4fa74d049cf7d64965afd6ce83c826cd313cec824ecfb9aacf36886090b495f60c0a4565b6005336020525f5260405f2054606051808203828111612c8057905090506080526080516005336020525f5260405f20555f54606051808203828111612c8057905090505f556020612cd15f395f5163a9059cbb60a05260405160c05260605160e052602060a0604460bc5f855af161274c573d5f5f3e3d5ffd5b3d61276357803b15612c805760016101005261277b565b60203d10612c805760a0518060011c612c8057610100525b61010090505115612c80576080516060516040517fdec5d726a70bdc7ab7e167507e34e068ab89db504d9ddcb08618c73a1f10a93e5f60a0a4565b6040366040376020612c915f395f51636d4ce63c608052604060806004609c5f855af16127e5573d5f5f3e3d5ffd5b60403d10612c80576080518060011c612c805760e05260a0516101005260e0905080516040526020810151606052506040516128265760075460605261282d565b6060516007555b6040518152606051602082015250565b6128486102006127b6565b610200506101a051600e54808202811583838304141715612c805790509050620186a081049050610200526060366102203760035460c05260045460e0526101a05161020051808201828110612c805790509050610100526128ab61028061176c565b61028080516102205260208101516102405260408101516102605250610220516003556102405160045560066101c0516020525f5260405f205461026051808201828110612c80579050905060066101c0516020525f5260405f2055600154610280526002546102a0526103e86102a051121561298757600d6102c0527f42656c6f77204d696e696d756d000000000000000000000000000000000000006102e0526102c0506102c051806102e001601f825f031636823750506308c379a06102805260206102a052601f19601f6102c051011660440161029cfd5b610280516101a051808203828111612c8057905090508060801c612c805761028052610280516001556102a0516002556020612cb15f395f5163a9059cbb6102c0526101e0516102e0526101a0516103005260206102c060446102dc5f855af16129f3573d5f5f3e3d5ffd5b3d612a0a57803b15612c8057600161032052612a23565b60203d10612c80576102c0518060011c612c8057610320525b61032090505115612c80576101c0516101e0516101a0517f322a69e46c4e1be12df82297341b3c5651c9f47519342541b412514bed8aac895f6102c0a46101a051815250565b6060366102203760035460e052600454610100526102005161012052600161014052612a96610280611803565b61028080516102205260208101516102405260408101516102605250610220516003556102405160045560066101e0516020525f5260405f205461020051808203828111612c80579050905060066101e0516020525f5260405f2055600154610280526020612cb15f395f516323b872dd6102a052336102c052306102e052610260516103005260206102a060646102bc5f855af1612b37573d5f5f3e3d5ffd5b3d612b4e57803b15612c8057600161032052612b67565b60203d10612c80576102a0518060011c612c8057610320525b61032090505115612c805761028051610260518060801c612c80578082018060801c612c80579050905060015561026051815250565b60066101c0516020525f5260405f20546102005261020051612bc3576001815250612c7e565b60056101c0516020525f5260405f20546102205261022051612be8575f815250612c7e565b6003546102405260045461026052610220516509184e72a0008102816509184e72a000820418612c80579050620124f8810281620124f8820418612c80579050610280526102005161024051808202811583838304141715612c8057905090506040526101e051606052610260516080525f60a052612c686102a06118a2565b6102a05161020052610200516102805110158152505b565b5f80fda165767970657283000309000b005b5f80fd000000000000000000000000530000000000000000000000000000000000000400000000000000000000000006efdbff2a14a7c8e15944d1f4a48f9f95f663a4000000000000000000000000ce410e58c17419df31de1a57656df0377746951200000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000844db640000000000000000000000000000000000000000000000000000000004b9a1f000000000000000000000000000000000000000000000000000000000b13138a8000000000000000000000000000000054a2b63d65d79d094abb66880000000000
Deployed Bytecode
0x6003361161000c5761163c565b5f3560e01c34612c8057637dc0d1d08118610033576020612c915f395f5160405260206040f35b6338d52e0f8118610050576020612cb15f395f5160405260206040f35b63d8dfeb45811861006d576020612cd15f395f5160405260206040f35b631ac0e2928118610083575f5460405260206040f35b636b8833c981186100a05760015460405260025460605260406040f35b638274109781186100bd5760035460405260045460605260406040f35b632b5fca1d81186100f65760243610612c80576004358060a01c612c805760405260056040516020525f5260405f205460605260206060f35b6377917072811861012f5760243610612c80576004358060a01c612c805760405260066040516020525f5260405f205460605260206060f35b63171ef0b281186101465760075460405260206040f35b633f0bc5bc811861016957600854604052600954606052600a5460805260606040f35b6363eded95811861018657600b54604052600c5460605260406040f35b63c45a015581186101a3576020612cf15f395f5160405260206040f35b635c975abb81186101ba57600d5460405260206040f35b63aba024f481186101d157600e5460405260206040f35b631655273281186101e857600f5460405260206040f35b63648c587481186101ff5760105460405260206040f35b6370a0823181186102385760243610612c80576004358060a01c612c805760405260116040516020525f5260405f205460605260206060f35b6318160ddd811861024f5760025460405260206040f35b63dd62ed3e81186102a55760443610612c80576004358060a01c612c80576040526024358060a01c612c805760605260126040516020525f5260405f20806060516020525f5260405f2090505460805260206080f35b6306fdde0381186103245760208060805260116040527f436f6720506f6f6c204c5020546f6b656e00000000000000000000000000000060605260408160800181516020830160208301815181525050808252508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b6395d89b4181186103a35760208060805260036040527f434c50000000000000000000000000000000000000000000000000000000000060605260408160800181516020830160208301815181525050808252508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506080f35b63313ce56781186103b957601260405260206040f35b63a9059cbb811861045b5760443610612c80576004358060a01c612c80576040526011336020525f5260405f208054602435808203828111612c80579050905081555060116040516020525f5260405f208054602435808201828110612c805790509050815550604051337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60243560605260206060a3600160605260206060f35b63095ea7b381186104d65760443610612c80576004358060a01c612c80576040526024356012336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f35b6323b872dd81186105bb5760643610612c80576004358060a01c612c80576040526024358060a01c612c805760605260126040516020525f5260405f2080336020525f5260405f2090508054604435808203828111612c80579050905081555060116040516020525f5260405f208054604435808203828111612c80579050905081555060116060516020525f5260405f208054604435808201828110612c8057905090508155506060516040517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60443560805260206080a3600160805260206080f35b6301e1d11481186105ef57600154604052600354606052606051604051808201828110612c80579050905060805260206080f35b6307a2d13a81186106185760243610612c8057602060043560405261061460c0611b89565b60c0f35b63c6e6f59281186106415760243610612c8057602060043560405261063d60a0611bef565b60a0f35b63402d267d811861068c5760243610612c80576004358060a01c612c80576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63ef8b30f781186106b55760243610612c805760206004356040526106b160a0611bef565b60a0f35b63b6b55f2581186106d25760243610612c8057336101c0526106f5565b636e553f65811861075f5760443610612c80576024358060a01c612c80576101c0525b6106fd611c4f565b6101c051604052600435606052610715610200611cb4565b610200516101e0526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7600435610200526101e051610220526040610200a360206101e0f35b63c63d75b681186107aa5760243610612c80576004358060a01c612c80576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63b3d7f6b981186107d35760243610612c805760206004356040526107cf60c0611b89565b60c0f35b63a0712d6881186107f05760243610612c8057336101c052610813565b6394bf804d81186108985760443610612c80576024358060a01c612c80576101c0525b61081b611c4f565b60043560405261082c610200611b89565b610200516101e0526101c0516040526101e05160605261084d610220611cb4565b61022051610200526101c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d76101e0516102205261020051610240526040610220a360206101e0f35b63ce96cb77811861092e5760243610612c80576004358060a01c612c805760c052601160c0516020525f5260405f20546040526108d560e0611b89565b60e0516020612cb15f395f516370a082316101005230610120526020610100602461011c845afa610908573d5f5f3e3d5ffd5b60203d10612c805761010090505180828118828410021890509050610140526020610140f35b630a28a47781186109b75760243610612c805760043560405261095160a0611bef565b60a0516020612cb15f395f516370a0823160c0523060e052602060c0602460dc845afa610980573d5f5f3e3d5ffd5b60203d10612c805760c090505160405261099b610100611bef565b6101005180828118828410021890509050610120526020610120f35b632e1a7d4d81186109d95760243610612c805733610320523361034052610a36565b62f714ce8118610a045760443610612c80576024358060a01c612c8057610320523361034052610a36565b63b460af948118610ac55760643610612c80576024358060a01c612c8057610320526044358060a01c612c8057610340525b610a3e6122ff565b600435604052610a4f610380611bef565b6103805161036052610320516040526103405160605261036051608052610a776103a061235e565b6103a051610380526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db6004356103a052610360516103c05260406103a0a46020610360f35b63d905777e8118610b585760243610612c80576004358060a01c612c805760a052601160a0516020525f5260405f20546020612cb15f395f516370a0823160c0523060e052602060c0602460dc845afa610b21573d5f5f3e3d5ffd5b60203d10612c805760c0905051604052610b3c610100611bef565b6101005180828118828410021890509050610120526020610120f35b634cdad5068118610be25760243610612c8057600435604052610b7b60c0611b89565b60c0516020612cb15f395f516370a0823160e0523061010052602060e0602460fc845afa610bab573d5f5f3e3d5ffd5b60203d10612c805760e0905051604052610bc6610120611bef565b6101205180828118828410021890509050610140526020610140f35b63db006a758118610c045760243610612c805733610320523361034052610c62565b637bde82f28118610c305760443610612c80576024358060a01c612c8057610320523361034052610c62565b63ba0876528118610cd75760643610612c80576024358060a01c612c8057610320526044358060a01c612c8057610340525b610c6a6122ff565b6103205160405261034051606052600435608052610c8961038061235e565b61038051610360526103405161032051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db61036051610380526004356103a0526040610380a46020610360f35b63f8ba4cff8118610cec57610cea6122ff565b005b6314fa10e18118610d2d5760443610612c80576004358060a01c612c805761032052610d166122ff565b61032051604052602435606052610d2b6125de565b005b63b5effcf38118610df25760443610612c80576004358060a01c612c805761032052610d576122ff565b61032051604052602435606052610d6c6126d1565b336101c0526007546101e052610d83610340612b9d565b61034051610df0576017610360527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103805261036050610360518061038001601f825f031636823750506308c379a061032052602061034052601f19601f61036051011660440161033cfd5b005b6332874ec78118610e485760443610612c80576004358060a01c612c80576040526024358060a01c612c805760605260136040516020525f5260405f20806060516020525f5260405f2090505460805260206080f35b634c01b7908118610ec35760443610612c80576004358060a01c612c80576040526024356013336020525f5260405f20806040516020525f5260405f20905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f35b63c5ebeaec8118610ee55760243610612c805733610340523361036052610f43565b634b3fd1488118610f115760443610612c80576024358060a01c612c8057610340523361036052610f43565b63d516418481186110665760643610612c80576024358060a01c612c8057610340526044358060a01c612c8057610360525b610f4b611c4f565b610f536122ff565b336103405114610f90576013610340516020525f5260405f2080336020525f5260405f2090508054600435808203828111612c8057905090508155505b6004356101a052610340516101c052610360516101e052610fb26103a061283d565b6103a05161038052610340516101c0526007546101e052610fd46103a0612b9d565b6103a0516110415760176103c0527f496e73756666696369656e7420436f6c6c61746572616c0000000000000000006103e0526103c0506103c051806103e001601f825f031636823750506308c379a06103805260206103a052601f19601f6103c051011660440161039cfd5b600854604052600954606052600a546080525f60a05261105f611e52565b6020610380f35b6322867d7881186110b15760443610612c80576004358060a01c612c8057610340526110906122ff565b6020610340516101e052602435610200526110ac610360612a69565b610360f35b63fe9f6e2481186110ce5760406110c96101206127b6565b610120f35b634914c00881186114745760643610612c80576004358060a01c612c8057610320526044358060a01c612c805761034052604036610360376111116103a06127b6565b6103a08051610380526020810151610360525061112c6122ff565b6060366103a0376003546104005260045461042052610320516101c052610360516101e05261115c610440612b9d565b6104405161129c576006610320516020525f5260405f20546104605260243561046051808281188284100218905090506103e052610460516103e051808203828111612c8057905090506006610320516020525f5260405f205561040051604052610420516060526103e0516080525f60a0526111da6104806116cf565b610480516103c0526103c0516201b5808102816201b580820418612c8057905061036051808202811583838304141715612c80579050905069152d02c7e14af6800000810490506103a0526005610320516020525f5260405f20546103a05111611244575f61124f565b610460516103e05118155b15611269576005610320516020525f5260405f20546103a0525b6005610320516020525f5260405f20546103a051808203828111612c8057905090506005610320516020525f5260405f20555b6103c051611309576018610440527f436f67506169723a205573657220697320736f6c76656e7400000000000000006104605261044050610440518061046001601f825f031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b6003546103c0518060801c612c80578082038060801c612c8057905090506003556004546103e0518060801c612c80578082038060801c612c8057905090506004555f546103a051808203828111612c8057905090505f556020612cd15f395f5163a9059cbb6104405261034051610460526103a051610480526020610440604461045c5f855af161139d573d5f5f3e3d5ffd5b3d6113b457803b15612c805760016104a0526113cd565b60203d10612c8057610440518060011c612c80576104a0525b6104a090505115612c80576020612cb15f395f516323b872dd61044052336104605230610480526103c0516104a0526020610440606461045c5f855af1611416573d5f5f3e3d5ffd5b3d61142d57803b15612c805760016104c052611446565b60203d10612c8057610440518060011c612c80576104c0525b6104c090505115612c80576001546103e0518060801c612c80578082018060801c612c805790509050600155005b63dba2d55381186114a95760243610612c80576020612cf15f395f513318612c805761c35060043511612c8057600435600e55005b635ec8ede481186114df5760243610612c80576020612cf15f395f513318612c8057620f424060043511612c8057600435601055005b638456cb598118611526576020612cf15f395f513318612c80576001600d55427f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e5f6040a2005b633f4ba83a811861156c576020612cf15f395f513318612c80575f600d55427fb96cc4c95dd57612feeeaed56e65b2fd6ba67b101d0592527f05756fafcab4b45f6040a2005b631c12948e811861163a576020612cf15f395f516326cfa27c606052602060606004607c845afa61159f573d5f5f3e3d5ffd5b60203d10612c80576060518060a01c612c805760a05260a0905051604052600854606052600954608052600a5460a05260a05160c05260116040516020525f5260405f205460c051808201828110612c80579050905060116040516020525f5260405f20555f600a556040515f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60c05160e052602060e0a3005b505b5f5ffd5b604051611652576080518152506116cd565b608051606051808202811583838304141715612c8057905090506040518015612c80578082049050905060a05260805160a051604051808202811583838304141715612c8057905090506060518015612c80578082049050905010156116c65760a05160018101818110612c8057905060a0525b60a0518152505b565b6060516116e15760805181525061176a565b608051604051808202811583838304141715612c8057905090506060518015612c80578082049050905060c05260a05161171b575f61174a565b60805160c051606051808202811583838304141715612c8057905090506040518015612c805780820490509050105b156117635760c05160018101818110612c8057905060c0525b60c0518152505b565b60c0516101205260e0516101405261012051604052610140516060526101005160805261179a610180611640565b610180516101605261012051610100518060801c612c80578082018060801c612c8057905090506101205261014051610160518060801c612c80578082018060801c612c8057905090506101405261012051815261014051602082015261016051604082015250565b60e0516101605261010051610180526101605160405261018051606052610120516080526101405160a0526118396101c06116cf565b6101c0516101a052610160516101a0518060801c612c80578082038060801c612c8057905090506101605261018051610120518060801c612c80578082038060801c612c805790509050610180526101605181526101805160208201526101a051604082015250565b60805161190557601e60c0527f4d6174683a206d756c5f646976206469766973696f6e206279207a65726f000060e05260c05060c0518060e001601f825f031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6060516040510960c0526060516040510260e0525f6101005260e05160c0511061195a5760e05160c0510361010052611969565b600160e05160c0510303610100525b610100516119b95760a05161197e575f611994565b6080518015612c80578060605160405109905015155b6119a75760805160e05104815250611b87565b600160805160e0510401815250611b87565b6101005160805111611a28576016610120527f4d6174683a206d756c5f646976206f766572666c6f77000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6080518015612c8057806060516040510990506101205260e051610120511115611a585760016101005103610100525b6101205160e0510360e0526080516080515f0316610140526101405160805104610160526101405160e0510460e052600161014051610140515f0304016101405261014051610100510260e0511760e05260026101605160030218610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805161016051026002036101805102610180526101805160e051026101a05260a051611b4e575f611b64565b6080518015612c80578060605160405109905015155b15611b7f576101a05160018101818110612c805790506101a0525b6101a0518152505b565b600154606052600254608052608051611ba757604051815250611bed565b6060516003548082018060801c612c80579050905060a05260405160a051808202811583838304141715612c8057905090506080518015612c8057808204905090508152505b565b6002546060526001546003548082018060801c612c805790509050608052608051611c1f57604051815250611c4d565b604051606051808202811583838304141715612c8057905090506080518015612c8057808204905090508152505b565b600d5415611cb257600b6040527f506169722050617573656400000000000000000000000000000000000000000060605260405060405180606001601f825f031636823750506308c379a05f526020602052601f19601f6040510116604401601cfd5b565b60015460805260025460a0526080516003548082018060801c612c80579050905060c0525f60e05260c051611cee5760605160e052611d1c565b60605160a051808202811583838304141715612c80579050905060c0518015612c80578082049050905060e0525b6103e760a05160e0518060801c612c80578082018060801c612c80579050905013611d4a575f815250611e50565b6001546060518060801c612c80578082018060801c612c8057905090506101005260025460e0518060801c612c80578082018060801c612c80579050905061012052610100516001556101205160025560116040516020525f5260405f205460e051808201828110612c805790509050610100526101005160116040516020525f5260405f20556020612cb15f395f516323b872dd6101205233610140523061016052606051610180526020610120606461013c5f855af1611e0e573d5f5f3e3d5ffd5b3d611e2557803b15612c805760016101a052611e3e565b60203d10612c8057610120518060011c612c80576101a0525b6101a090505115612c805760e0518152505b565b60405160c05260605160e05260805161010052428060401c612c805760e052600354610120526004546101405261014051611ebd576020612d515f395f5160c05114611ea5576020612d515f395f5160c0525b60c05160085560e05160095561010051600a556122fd565b604036610160376001546101a0526002546101c0526101205160c051808202811583838304141715612c80579050905060a051808202811583838304141715612c805790509050670de0b6b3a7640000810490506101605261012051610160518060801c612c80578082018060801c612c805790509050610120526101a05161012051808201828110612c8057905090506101e05261016051600f54808202811583838304141715612c805790509050620f42408104905061020052610200516101c051808202811583838304141715612c8057905090506101e0518015612c8057808204905090506101805261010051610180518060801c612c80578082018060801c612c805790509050610100526101c051610180518060801c612c80578082018060801c612c805790509050600255610120516003556101405160045561012051670de0b6b3a7640000810281670de0b6b3a7640000820418612c805790506101e0518015612c805780820490509050610220526020612d115f395f516102205110612162576020612d315f395f5161022051111561226657610220516020612d315f395f51808203828111612c805790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612c805790506020612d315f395f518015612c805780820490509050610240526020612db15f395f516102405161024051808202811583838304141715612c80579050905060a051808202811583838304141715612c805790509050808201828110612c8057905090506102605260c05161026051808202811583838304141715612c8057905090506020612db15f395f518015612c8057808204905090508060401c612c8057610280526102805160c0526020612d915f395f51610280511315612266576020612d915f395f5160c052612266565b6020612d115f395f5161022051808203828111612c805790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612c805790506020612d115f395f518015612c805780820490509050610240526020612db15f395f516102405161024051808202811583838304141715612c80579050905060a051808202811583838304141715612c805790509050808201828110612c8057905090506102605260c0516020612db15f395f51808202811583838304141715612c805790509050610260518015612c8057808204905090508060401c612c8057610280526102805160c0526020612d715f395f5160c0511215612266576020612d715f395f5160c0525b428060401c612c8057600c548082038060401c612c805790509050610240526203f48161024051126122e957600b5460c051136122a857601054600f556122e9565b60c051600b548082038060401c612c805790509050610260526361830fc161026051126122e957428060401c612c8057600c5560c051600b55620f4240600f555b60c05160085560e05160095561010051600a555b565b6008546102a0526009546102c052600a546102e052426102c051808203828111612c80579050905061030052610300516123385761235c565b6102a0516040526102c0516060526102e0516080526103005160a05261235c611e52565b565b336060511461241a5760805160126060516020525f5260405f2080336020525f5260405f2090505410156123e857601660a0527f496e73756666696369656e7420416c6c6f77616e63650000000000000000000060c05260a05060a0518060c001601f825f031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b60126060516020525f5260405f2080336020525f5260405f2090508054608051808203828111612c8057905090508155505b60015460a05260025460c05260a0516003548082018060801c612c80579050905060e05260805160e051808202811583838304141715612c80579050905060c0518015612c8057808204905090506101005260a051610100518060801c612c80578082038060801c612c80579050905060a05260c0516080518060801c612c80578082038060801c612c80579050905060c0526103e860c051121561251c57600d610120527f42656c6f77204d696e696d756d000000000000000000000000000000000000006101405261012050610120518061014001601f825f031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60a05160015560c05160025560116060516020525f5260405f2054608051808203828111612c805790509050610120526101205160116060516020525f5260405f20556020612cb15f395f5163a9059cbb610140526040516101605261010051610180526020610140604461015c5f855af161259a573d5f5f3e3d5ffd5b3d6125b157803b15612c805760016101a0526125ca565b60203d10612c8057610140518060011c612c80576101a0525b6101a090505115612c805761010051815250565b60056040516020525f5260405f2054606051808201828110612c80579050905060805260805160056040516020525f5260405f20555f5460a05260a051606051808201828110612c8057905090505f556020612cd15f395f516323b872dd60c0523360e052306101005260605161012052602060c0606460dc5f855af1612667573d5f5f3e3d5ffd5b3d61267e57803b15612c8057600161014052612696565b60203d10612c805760c0518060011c612c8057610140525b61014090505115612c80576080516060516040517fe3f4fa74d049cf7d64965afd6ce83c826cd313cec824ecfb9aacf36886090b495f60c0a4565b6005336020525f5260405f2054606051808203828111612c8057905090506080526080516005336020525f5260405f20555f54606051808203828111612c8057905090505f556020612cd15f395f5163a9059cbb60a05260405160c05260605160e052602060a0604460bc5f855af161274c573d5f5f3e3d5ffd5b3d61276357803b15612c805760016101005261277b565b60203d10612c805760a0518060011c612c8057610100525b61010090505115612c80576080516060516040517fdec5d726a70bdc7ab7e167507e34e068ab89db504d9ddcb08618c73a1f10a93e5f60a0a4565b6040366040376020612c915f395f51636d4ce63c608052604060806004609c5f855af16127e5573d5f5f3e3d5ffd5b60403d10612c80576080518060011c612c805760e05260a0516101005260e0905080516040526020810151606052506040516128265760075460605261282d565b6060516007555b6040518152606051602082015250565b6128486102006127b6565b610200506101a051600e54808202811583838304141715612c805790509050620186a081049050610200526060366102203760035460c05260045460e0526101a05161020051808201828110612c805790509050610100526128ab61028061176c565b61028080516102205260208101516102405260408101516102605250610220516003556102405160045560066101c0516020525f5260405f205461026051808201828110612c80579050905060066101c0516020525f5260405f2055600154610280526002546102a0526103e86102a051121561298757600d6102c0527f42656c6f77204d696e696d756d000000000000000000000000000000000000006102e0526102c0506102c051806102e001601f825f031636823750506308c379a06102805260206102a052601f19601f6102c051011660440161029cfd5b610280516101a051808203828111612c8057905090508060801c612c805761028052610280516001556102a0516002556020612cb15f395f5163a9059cbb6102c0526101e0516102e0526101a0516103005260206102c060446102dc5f855af16129f3573d5f5f3e3d5ffd5b3d612a0a57803b15612c8057600161032052612a23565b60203d10612c80576102c0518060011c612c8057610320525b61032090505115612c80576101c0516101e0516101a0517f322a69e46c4e1be12df82297341b3c5651c9f47519342541b412514bed8aac895f6102c0a46101a051815250565b6060366102203760035460e052600454610100526102005161012052600161014052612a96610280611803565b61028080516102205260208101516102405260408101516102605250610220516003556102405160045560066101e0516020525f5260405f205461020051808203828111612c80579050905060066101e0516020525f5260405f2055600154610280526020612cb15f395f516323b872dd6102a052336102c052306102e052610260516103005260206102a060646102bc5f855af1612b37573d5f5f3e3d5ffd5b3d612b4e57803b15612c8057600161032052612b67565b60203d10612c80576102a0518060011c612c8057610320525b61032090505115612c805761028051610260518060801c612c80578082018060801c612c80579050905060015561026051815250565b60066101c0516020525f5260405f20546102005261020051612bc3576001815250612c7e565b60056101c0516020525f5260405f20546102205261022051612be8575f815250612c7e565b6003546102405260045461026052610220516509184e72a0008102816509184e72a000820418612c80579050620124f8810281620124f8820418612c80579050610280526102005161024051808202811583838304141715612c8057905090506040526101e051606052610260516080525f60a052612c686102a06118a2565b6102a05161020052610200516102805110158152505b565b5f80fda165767970657283000309000b000000000000000000000000ce410e58c17419df31de1a57656df03777469512000000000000000000000000530000000000000000000000000000000000000400000000000000000000000006efdbff2a14a7c8e15944d1f4a48f9f95f663a4000000000000000000000000babd55549c266c6755b99173fe7604238d04117d00000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000844db640000000000000000000000000000000000000000000000000000000004b9a1f000000000000000000000000000000000000000000000000000000000b13138a8000000000000000000000000000000054a2b63d65d79d094abb66880000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000530000000000000000000000000000000000000400000000000000000000000006efdbff2a14a7c8e15944d1f4a48f9f95f663a4000000000000000000000000Ce410E58C17419DF31dE1a57656dF0377746951200000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000844db640000000000000000000000000000000000000000000000000000000004b9a1f000000000000000000000000000000000000000000000000000000000b13138a8000000000000000000000000000000054a2b63d65d79d094abb66880000000000
-----Decoded View---------------
Arg [0] : _asset (address): 0x5300000000000000000000000000000000000004
Arg [1] : _collateral (address): 0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4
Arg [2] : _oracle (address): 0xCe410E58C17419DF31dE1a57656dF03777469512
Arg [3] : min_target_utilization (uint256): 500000000000000000
Arg [4] : max_target_utilization (uint256): 600000000000000000
Arg [5] : starting_interest_per_second (uint64): 2219685440
Arg [6] : min_interest (uint64): 1268391680
Arg [7] : max_interest (uint64): 47564688000
Arg [8] : elasticity (uint256): 28800000000000000000000000000000000000000
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000005300000000000000000000000000000000000004
Arg [1] : 00000000000000000000000006efdbff2a14a7c8e15944d1f4a48f9f95f663a4
Arg [2] : 000000000000000000000000Ce410E58C17419DF31dE1a57656dF03777469512
Arg [3] : 00000000000000000000000000000000000000000000000006f05b59d3b20000
Arg [4] : 0000000000000000000000000000000000000000000000000853a0d2313c0000
Arg [5] : 00000000000000000000000000000000000000000000000000000000844db640
Arg [6] : 000000000000000000000000000000000000000000000000000000004b9a1f00
Arg [7] : 0000000000000000000000000000000000000000000000000000000b13138a80
Arg [8] : 00000000000000000000000000000054a2b63d65d79d094abb66880000000000
Loading...
Loading
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.