ETH Price: $4,029.98 (+2.66%)

Contract

0xB42e34Bf1f8627189e099ABDB069B9D73B521E4F
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction and > 10 Token Transfers found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x61224551234340092025-09-24 16:12:2325 days ago1758730343  Contract Creation0 ETH
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x970385BB...Afd9c6144
The constructor portion of the code might be different and could alter the actual behaviour of the contract
This is an ERC-5202 Blueprint contract

Contract Name:
LEVAMM

Compiler Version
vyper:0.4.3

Optimization Enabled:
Yes

Other Settings:
default evmVersion, None license

Contract Source Code (Vyper Json-Input format)

File 1 of 2 : AMM.vy
# @version 0.4.3
"""
@title LEVAMM
@notice Automatic market maker which keeps constant leverage
@author Scientia Spectra AG
@license Copyright (c) 2025
"""
from snekmate.utils import math


interface IERC20:
    def decimals() -> uint256: view
    def approve(_to: address, _value: uint256) -> bool: nonpayable
    def transfer(_to: address, _value: uint256) -> bool: nonpayable
    def transferFrom(_from: address, _to: address, _value: uint256) -> bool: nonpayable
    def balanceOf(user: address) -> uint256: view

interface PriceOracle:
    def price_w() -> uint256: nonpayable
    def price() -> uint256: view

interface LT:
    def distribute_borrower_fees(): nonpayable


struct AMMState:
    collateral: uint256
    debt: uint256
    x0: uint256

struct Pair:
    collateral: uint256
    debt: uint256

struct OraclizedValue:
    p_o: uint256
    value: uint256


LEVERAGE: public(immutable(uint256))
LEV_RATIO: immutable(uint256)
MIN_SAFE_DEBT: immutable(uint256)
MAX_SAFE_DEBT: immutable(uint256)
LT_CONTRACT: public(immutable(address))
COLLATERAL: public(immutable(IERC20))
STABLECOIN: public(immutable(IERC20))
PRICE_ORACLE_CONTRACT: public(immutable(PriceOracle))

COLLATERAL_PRECISION: immutable(uint256)

MAX_FEE: constant(uint256) = 10**17
fee: public(uint256)

MAX_RATE: constant(uint256) = 10**18 // (365 * 86400)  # Not more than 100% APR

collateral_amount: public(uint256)
debt: uint256
rate: public(uint256)
rate_mul: public(uint256)
rate_time: uint256

minted: public(uint256)
redeemed: public(uint256)

is_killed: public(bool)


event TokenExchange:
    buyer: indexed(address)
    sold_id: uint256
    tokens_sold: uint256
    bought_id: uint256
    tokens_bought: uint256
    fee: uint256
    price_oracle: uint256

event AddLiquidityRaw:
    token_amounts: uint256[2]
    invariant: uint256
    price_oracle: uint256

event RemoveLiquidityRaw:
    collateral_change: uint256
    debt_change: uint256

event SetRate:
    rate: uint256
    rate_mul: uint256
    time: uint256

event CollectFees:
    amount: uint256
    new_supply: uint256

event SetFee:
    fee: uint256

event SetKilled:
    is_killed: bool


@deploy
def __init__(lt_contract: address,
             stablecoin: IERC20, collateral: IERC20, leverage: uint256,
             fee: uint256, price_oracle_contract: PriceOracle):
    LT_CONTRACT = lt_contract
    STABLECOIN = stablecoin
    COLLATERAL = collateral
    LEVERAGE = leverage
    assert fee <= MAX_FEE, "Fee too high"
    self.fee = fee
    PRICE_ORACLE_CONTRACT = price_oracle_contract

    COLLATERAL_PRECISION = 10**(18 - staticcall COLLATERAL.decimals())
    assert staticcall STABLECOIN.decimals() == 18
    assert leverage > 10**18

    denominator: uint256 = 2 * leverage - 10**18
    LEV_RATIO = leverage**2 * 10**18 // denominator**2

    # 1 / (4 * L**2)
    MIN_SAFE_DEBT = 10**54 // (4 * leverage**2)
    # (2 * L - 1)**2 / (4 * L**2) - 1 / (8 * L**2)
    MAX_SAFE_DEBT = denominator**2 * 10**18 // (4 * leverage**2) - 10**54 // (8 * leverage**2)

    self.rate_mul = 10**18
    self.rate_time = block.timestamp

    extcall stablecoin.approve(LT_CONTRACT, max_value(uint256), default_return_value=True)
    extcall collateral.approve(LT_CONTRACT, max_value(uint256), default_return_value=True)


# Math
@internal
@pure
def sqrt(arg: uint256) -> uint256:
    return isqrt(arg)


@internal
@view
def get_x0(p_oracle: uint256, collateral: uint256, debt: uint256, safe_limits: bool) -> uint256:
    # Safe limits:
    # debt >= 0
    # debt <= coll_value * 10**18 // (4 * LEV_RATIO)  ( == 9 / 16 * coll_value)
    # debt in equilibrium = coll_value * (LEVERAGE - 1.0) / LEVERAGE  ( == 1/2 * coll_value)
    # When L=2, critical value of debt corresponds to p_amm = 9/16 * p_o
    # Just in case, we limit between (1/16 .. 8.5/16) which is a somewaht tighter range

    coll_value: uint256 = p_oracle * collateral * COLLATERAL_PRECISION // 10**18

    if safe_limits:
        assert debt >= coll_value * MIN_SAFE_DEBT // 10**18, "Unsafe min"
        assert debt <= coll_value * MAX_SAFE_DEBT // 10**18, "Unsafe max"

    D: uint256 = coll_value**2 - 4 * coll_value * LEV_RATIO // 10**18 * debt
    return (coll_value + self.sqrt(D)) * 10**18 // (2 * LEV_RATIO)
###


@internal
@view
def _rate_mul() -> uint256:
    """
    @notice Rate multiplier which is 1.0 + integral(rate, dt)
    @return Rate multiplier in units where 1.0 == 1e18
    """
    return unsafe_div(self.rate_mul * (10**18 + self.rate * (block.timestamp - self.rate_time)), 10**18)


@external
@view
def get_rate_mul() -> uint256:
    """
    @notice Rate multiplier which is 1.0 + integral(rate, dt)
    @return Rate multiplier in units where 1.0 == 1e18
    """
    return self._rate_mul()


@external
@nonreentrant
def set_rate(rate: uint256) -> uint256:
    """
    @notice Set interest rate. That affects the dependence of AMM base price over time
    @param rate New rate in units of int(fraction * 1e18) per second
    @return rate_mul multiplier (e.g. 1.0 + integral(rate, dt))
    """
    assert msg.sender == LT_CONTRACT, "Access"
    assert rate <= MAX_RATE, "Rate too high"
    rate_mul: uint256 = self._rate_mul()
    self.debt = self.debt * rate_mul // self.rate_mul
    self.rate_mul = rate_mul
    self.rate_time = block.timestamp
    self.rate = rate
    log SetRate(rate=rate, rate_mul=rate_mul, time=block.timestamp)
    return rate_mul


@internal
@view
def _debt() -> uint256:
    return self.debt * self._rate_mul() // self.rate_mul


@internal
def _debt_w() -> uint256:
    rate_mul: uint256 = self._rate_mul()
    debt: uint256 = self.debt * rate_mul // self.rate_mul
    self.rate_mul = rate_mul
    self.rate_time = block.timestamp
    return debt


@external
@view
def get_debt() -> uint256:
    """
    @notice Debt of the AMM
    """
    return self._debt()


@external
@view
def outdated_debt() -> uint256:
    return self.debt


@external
@view
def get_state() -> AMMState:
    """
    @notice State of the AMM
    @return Returns a data strucuture which contains (collateral, debt, x0)
    """
    p_o: uint256 = staticcall PRICE_ORACLE_CONTRACT.price()
    state: AMMState = empty(AMMState)
    state.collateral = self.collateral_amount
    state.debt = self._debt()
    state.x0 = self.get_x0(p_o, state.collateral, state.debt, False)
    return state


@external
@view
def get_dy(i: uint256, j: uint256, in_amount: uint256) -> uint256:
    """
    @notice Function to preview the result of exchange in the AMM
    @param i Index of input coin (0 = stablecoin, 1 = LP token collateral)
    @param j Index of output coin
    @param in_amount Amount of coin i
    @return Amount of coin j to be received
    """
    assert (i == 0 and j == 1) or (i == 1 and j == 0)

    p_o: uint256 = staticcall PRICE_ORACLE_CONTRACT.price()
    collateral: uint256 = self.collateral_amount  # == y_initial
    debt: uint256 = self._debt()
    x_initial: uint256 = self.get_x0(p_o, collateral, debt, False) - debt

    if i == 0:  # Buy collateral
        assert in_amount <= debt, "Amount too large"
        x: uint256 = x_initial + in_amount
        y: uint256 = math._ceil_div(x_initial * collateral, x)
        return (collateral - y) * (10**18 - self.fee) // 10**18

    else:  # Sell collateral
        y: uint256 = collateral + in_amount
        x: uint256 = math._ceil_div(x_initial * collateral, y)
        return (x_initial - x) * (10**18 - self.fee) // 10**18


@external
@view
def get_p() -> uint256:
    """
    @notice Returns state price of the AMM itself
    """
    p_o: uint256 = staticcall PRICE_ORACLE_CONTRACT.price()
    collateral: uint256 = self.collateral_amount
    debt: uint256 = self._debt()
    return (self.get_x0(p_o, collateral, debt, False) - debt) * (10**18 // COLLATERAL_PRECISION) // collateral


@external
@nonreentrant
def exchange(i: uint256, j: uint256, in_amount: uint256, min_out: uint256, _for: address = msg.sender) -> uint256:
    """
    @notice Exchanges two coins, callable by anyone
    @param i Index of input coin (0 = stablecoin, 1 = LP token collateral)
    @param j Output coin index
    @param in_amount Amount of input coin to swap
    @param min_out Minimal amount to get as output
    @param _for Address to send coins to
    @return Amount of coins given in/out
    """
    assert (i == 0 and j == 1) or (i == 1 and j == 0)
    assert not self.is_killed

    collateral: uint256 = self.collateral_amount  # == y_initial
    assert collateral > 0, "Empty AMM"
    debt: uint256 = self._debt_w()
    p_o: uint256 = extcall PRICE_ORACLE_CONTRACT.price_w()
    x0: uint256 = self.get_x0(p_o, collateral, debt, False)
    x_initial: uint256 = x0 - debt

    out_amount: uint256 = 0
    fee: uint256 = self.fee

    if i == 0:  # Trader buys collateral from us
        x: uint256 = x_initial + in_amount
        y: uint256 = math._ceil_div(x_initial * collateral, x)
        out_amount = (collateral - y) * (10**18 - fee) // 10**18
        assert out_amount >= min_out, "Slippage"
        debt -= in_amount
        collateral -= out_amount
        self.redeemed += in_amount
        assert extcall STABLECOIN.transferFrom(msg.sender, self, in_amount, default_return_value=True)
        assert extcall COLLATERAL.transfer(_for, out_amount, default_return_value=True)

    else:  # Trader sells collateral to us
        y: uint256 = collateral + in_amount
        x: uint256 = math._ceil_div(x_initial * collateral, y)
        out_amount = (x_initial - x) * (10**18 - fee) // 10**18
        assert out_amount >= min_out, "Slippage"
        debt += out_amount
        self.minted += out_amount
        collateral = y
        assert extcall COLLATERAL.transferFrom(msg.sender, self, in_amount, default_return_value=True)
        assert extcall STABLECOIN.transfer(_for, out_amount, default_return_value=True)

    # This call also will not allow to get too close to the untradable region
    assert self.get_x0(p_o, collateral, debt, True) >= x0, "Bad final state"

    self.collateral_amount = collateral
    self.debt = debt

    log TokenExchange(buyer=msg.sender, sold_id=i, tokens_sold=in_amount,
                      bought_id=j, tokens_bought=out_amount, fee=fee, price_oracle=p_o)

    if LT_CONTRACT != empty(address) and LT_CONTRACT.is_contract:
        self._collect_fees()
        extcall LT(LT_CONTRACT).distribute_borrower_fees()

    return out_amount


@external
def _deposit(d_collateral: uint256, d_debt: uint256) -> OraclizedValue:
    assert msg.sender == LT_CONTRACT, "Access violation"
    assert not self.is_killed

    p_o: uint256 = extcall PRICE_ORACLE_CONTRACT.price_w()
    collateral: uint256 = self.collateral_amount  # == y_initial
    debt: uint256 = self._debt_w()

    debt += d_debt
    collateral += d_collateral
    self.minted += d_debt

    self.debt = debt
    self.collateral_amount = collateral
    # Assume that transfer of collateral happened already (as a result of exchange)

    value_after: uint256 = self.get_x0(p_o, collateral, debt, True) * 10**18 // (2 * LEVERAGE - 10**18)  # Value in fiat

    log AddLiquidityRaw(token_amounts=[d_collateral, d_debt], invariant=value_after, price_oracle=p_o)
    return OraclizedValue(p_o=p_o, value=value_after)


@external
def _withdraw(frac: uint256) -> Pair:
    assert msg.sender == LT_CONTRACT, "Access violation"

    collateral: uint256 = self.collateral_amount  # == y_initial
    debt: uint256 = self._debt_w()

    d_collateral: uint256 = collateral * frac // 10**18
    d_debt: uint256 = math._ceil_div(debt * frac, 10**18)

    self.collateral_amount -= d_collateral
    self.debt = debt - d_debt
    self.redeemed += d_debt

    log RemoveLiquidityRaw(collateral_change=d_collateral, debt_change=d_debt)

    return Pair(collateral=d_collateral, debt=d_debt)


@external
@view
def coins(i: uint256) -> IERC20:
    """
    @notice Coins in the AMM: 0 - stablecoin, 1 - collateral (LP)
    """
    return [STABLECOIN, COLLATERAL][i]


@external
@view
def value_oracle() -> OraclizedValue:
    """
    @notice Non-manipulable oracle which shows value of the whole AMM valued in stablecoin
    """
    p_o: uint256 = staticcall PRICE_ORACLE_CONTRACT.price()
    collateral: uint256 = self.collateral_amount  # == y_initial
    debt: uint256 = self._debt()
    return OraclizedValue(p_o=p_o, value=self.get_x0(p_o, collateral, debt, False) * 10**18 // (2 * LEVERAGE - 10**18))


@external
@view
def value_oracle_for(collateral: uint256, debt: uint256) -> OraclizedValue:
    """
    @notice Total value oracle for any specified amounts of collateral and debt in the AMM
    """
    p_o: uint256 = staticcall PRICE_ORACLE_CONTRACT.price()
    return OraclizedValue(p_o=p_o, value=self.get_x0(p_o, collateral, debt, False) * 10**18 // (2 * LEVERAGE - 10**18))


@external
@view
def value_change(collateral_amount: uint256, borrowed_amount: uint256, is_deposit: bool) -> OraclizedValue:
    """
    @notice Change in the value oracle
    @param collateral_amount Amount of collateral to deposit/withdraw to AMM
    @param borrowed_amount Amount to borrow or repay when depositing/withdrawing
    @param is_deposit Is it a deposit or withdrawal
    @return (p_oracle, value)
    """
    p_o: uint256 = staticcall PRICE_ORACLE_CONTRACT.price()
    collateral: uint256 = self.collateral_amount  # == y_initial
    debt: uint256 = self._debt()

    if is_deposit:
        collateral += collateral_amount
        debt += borrowed_amount
    else:
        collateral -= collateral_amount
        debt -= borrowed_amount

    x0_after: uint256 = self.get_x0(p_o, collateral, debt, is_deposit)

    return OraclizedValue(
        p_o = p_o,
        value = x0_after * 10**18 // (2 * LEVERAGE - 10**18))


@external
@view
def max_debt() -> uint256:
    """
    @notice Maximum amount of debt which the AMM can possibly take
    """
    return staticcall STABLECOIN.balanceOf(self) + self._debt()


@external
@view
def accumulated_interest() -> uint256:
    """
    @notice Calculate the amount of fees obtained from the interest
    """
    minted: uint256 = self.minted
    return unsafe_sub(max(self._debt() + self.redeemed, minted), minted)


@internal
def _collect_fees() -> uint256:
    """
    @notice Collect the fees charged as interest.
    """
    assert not self.is_killed

    debt: uint256 = self._debt_w()
    self.debt = debt
    minted: uint256 = self.minted
    to_be_redeemed: uint256 = debt + self.redeemed
    # Difference between to_be_redeemed and minted amount is exactly due to interest charged
    if to_be_redeemed > minted:
        self.minted = to_be_redeemed
        to_be_redeemed = unsafe_sub(to_be_redeemed, minted)  # Now this is the fees to charge
        stables_in_amm: uint256 = staticcall STABLECOIN.balanceOf(self)
        if stables_in_amm < to_be_redeemed:
            self.minted -= (to_be_redeemed - stables_in_amm)
            to_be_redeemed = stables_in_amm
        assert extcall STABLECOIN.transfer(LT_CONTRACT, to_be_redeemed, default_return_value=True)
        log CollectFees(amount=to_be_redeemed, new_supply=debt)
        return to_be_redeemed
    else:
        log CollectFees(amount=0, new_supply=debt)
        return 0


@external
@nonreentrant
def collect_fees() -> uint256:
    """
    @notice Collect the fees charged as interest.
    """
    return self._collect_fees()


@external
def set_killed(is_killed: bool):
    """
    @notice Kill (True) or unkill (False) the pool
    """
    assert msg.sender == LT_CONTRACT, "Access"
    self.is_killed = is_killed
    log SetKilled(is_killed=is_killed)


@external
@nonreentrant
@view
def check_nonreentrant():
    pass


@external
def set_fee(fee: uint256):
    """
    @notice Set pool's fee for exchanges LP<>stacoin (all the fees go to LPs)
    """
    assert msg.sender == LT_CONTRACT, "Access"
    assert fee <= MAX_FEE
    self.fee = fee
    log SetFee(fee=fee)

File 2 of 2 : math.vy
# pragma version ~=0.4.3
# pragma nonreentrancy off
"""
@title Standard Mathematical Utility Functions
@custom:contract-name math
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
@custom:coauthor bout3fiddy
@notice These functions implement standard mathematical utility
        functions that are missing in the Vyper language. If a
        function is inspired by an existing implementation, it
        is properly referenced in the function docstring. The
        following functions have been added for convenience:
        - `_uint256_average` (`internal` `pure` function),
        - `_int256_average` (`internal` `pure` function),
        - `_ceil_div` (`internal` `pure` function),
        - `_signum` (`internal` `pure` function),
        - `_mul_div` (`internal` `pure` function),
        - `_log2` (`internal` `pure` function),
        - `_log10` (`internal` `pure` function),
        - `_log256` (`internal` `pure` function),
        - `_wad_ln` (`internal` `pure` function),
        - `_wad_exp` (`internal` `pure` function),
        - `_cbrt` (`internal` `pure` function),
        - `_wad_cbrt` (`internal` `pure` function).
"""


@deploy
@payable
def __init__():
    """
    @dev To omit the opcodes for checking the `msg.value`
         in the creation-time EVM bytecode, the constructor
         is declared as `payable`.
    """
    pass


@internal
@pure
def _uint256_average(x: uint256, y: uint256) -> uint256:
    """
    @dev Returns the average of two 32-byte unsigned integers.
    @notice Note that the result is rounded towards zero. For
            more details on finding the average of two unsigned
            integers without an overflow, please refer to:
            https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223.
    @param x The first 32-byte unsigned integer of the data set.
    @param y The second 32-byte unsigned integer of the data set.
    @return uint256 The 32-byte average (rounded towards zero) of
            `x` and `y`.
    """
    return unsafe_add(x & y, (x ^ y) >> 1)


@internal
@pure
def _int256_average(x: int256, y: int256) -> int256:
    """
    @dev Returns the average of two 32-byte signed integers.
    @notice Note that the result is rounded towards infinity.
            For more details on finding the average of two signed
            integers without an overflow, please refer to:
            https://patents.google.com/patent/US6007232A/en.
    @param x The first 32-byte signed integer of the data set.
    @param y The second 32-byte signed integer of the data set.
    @return int256 The 32-byte average (rounded towards infinity)
            of `x` and `y`.
    """
    return unsafe_add(unsafe_add(x >> 1, y >> 1), x & y & 1)


@internal
@pure
def _ceil_div(x: uint256, y: uint256) -> uint256:
    """
    @dev Calculates "ceil(x / y)" for any strictly positive `y`.
    @notice The implementation 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 numerator.
    @param y The 32-byte denominator.
    @return uint256 The 32-byte rounded up result of "x/y".
    """
    assert y != empty(uint256), "math: ceil_div division by zero"
    # Due to a known compiler bug (https://github.com/vyperlang/vyper/issues/3480),
    # we use `0` instead of `empty(uint256)` as return value.
    return 0 if (x == empty(uint256)) else unsafe_add(unsafe_div(x - 1, y), 1)


@internal
@pure
def _signum(x: int256) -> int256:
    """
    @dev Returns the indication of the sign of a 32-byte signed integer.
    @notice The function returns `-1` if `x < 0`, `0` if `x == 0`, and `1`
            if `x > 0`. For more details on finding the sign of a signed
            integer, please refer to:
            https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign.
    @param x The 32-byte signed integer variable.
    @return int256 The 32-byte sign indication (`1`, `0`, or `-1`) of `x`.
    """
    return unsafe_sub(convert((x > empty(int256)), int256), convert((x < empty(int256)), int256))


@internal
@pure
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)

    # Handling of non-overflow cases, 256 by 256 division.
    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)

        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(empty(uint256), 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


@internal
@pure
def _log2(x: uint256, roundup: bool) -> uint256:
    """
    @dev Returns the log in base 2 of `x`, following the selected
         rounding direction.
    @notice Note that it returns `0` if given `0`. The implementation
            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 variable.
    @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.
    """
    # For the special case `x == 0`, we already return `0` here in order
    # not to iterate through the remaining code.
    if x == empty(uint256):
        return empty(uint256)

    value: uint256 = x
    result: uint256 = empty(uint256)

    # The following lines cannot overflow because we have the well-known
    # decay behaviour of `log2(max_value(uint256)) < max_value(uint256)`.
    if x >> 128 != empty(uint256):
        x >>= 128
        result = 128
    if x >> 64 != empty(uint256):
        x >>= 64
        result = unsafe_add(result, 64)
    if x >> 32 != empty(uint256):
        x >>= 32
        result = unsafe_add(result, 32)
    if x >> 16 != empty(uint256):
        x >>= 16
        result = unsafe_add(result, 16)
    if x >> 8 != empty(uint256):
        x >>= 8
        result = unsafe_add(result, 8)
    if x >> 4 != empty(uint256):
        x >>= 4
        result = unsafe_add(result, 4)
    if x >> 2 != empty(uint256):
        x >>= 2
        result = unsafe_add(result, 2)
    if x >> 1 != empty(uint256):
        result = unsafe_add(result, 1)

    if roundup and (1 << result) < value:
        result = unsafe_add(result, 1)

    return result


@internal
@pure
def _log10(x: uint256, roundup: bool) -> uint256:
    """
    @dev Returns the log in base 10 of `x`, following the selected
         rounding direction.
    @notice Note that it returns `0` if given `0`. The implementation
            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 variable.
    @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.
    """
    # For the special case `x == 0`, we already return `0` here in order
    # not to iterate through the remaining code.
    if x == empty(uint256):
        return empty(uint256)

    value: uint256 = x
    result: uint256 = empty(uint256)

    # The following lines cannot overflow because we have the well-known
    # decay behaviour of `log10(max_value(uint256)) < max_value(uint256)`.
    if x >= 10 ** 64:
        x = unsafe_div(x, 10 ** 64)
        result = 64
    if x >= 10 ** 32:
        x = unsafe_div(x, 10 ** 32)
        result = unsafe_add(result, 32)
    if x >= 10 ** 16:
        x = unsafe_div(x, 10 ** 16)
        result = unsafe_add(result, 16)
    if x >= 10 ** 8:
        x = unsafe_div(x, 10 ** 8)
        result = unsafe_add(result, 8)
    if x >= 10 ** 4:
        x = unsafe_div(x, 10 ** 4)
        result = unsafe_add(result, 4)
    if x >= 10 ** 2:
        x = unsafe_div(x, 10 ** 2)
        result = unsafe_add(result, 2)
    if x >= 10:
        result = unsafe_add(result, 1)

    if roundup and (10 ** result) < value:
        result = unsafe_add(result, 1)

    return result


@internal
@pure
def _log256(x: uint256, roundup: bool) -> uint256:
    """
    @dev Returns the log in base 256 of `x`, following the selected
         rounding direction.
    @notice Note that it returns `0` if given `0`. Also, adding one to the
            rounded down result gives the number of pairs of hex symbols
            needed to represent `x` as a hex string. The implementation 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 variable.
    @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.
    """
    # For the special case `x == 0`, we already return `0` here in order
    # not to iterate through the remaining code.
    if x == empty(uint256):
        return empty(uint256)

    value: uint256 = x
    result: uint256 = empty(uint256)

    # The following lines cannot overflow because we have the well-known
    # decay behaviour of `log256(max_value(uint256)) < max_value(uint256)`.
    if x >> 128 != empty(uint256):
        x >>= 128
        result = 16
    if x >> 64 != empty(uint256):
        x >>= 64
        result = unsafe_add(result, 8)
    if x >> 32 != empty(uint256):
        x >>= 32
        result = unsafe_add(result, 4)
    if x >> 16 != empty(uint256):
        x >>= 16
        result = unsafe_add(result, 2)
    if x >> 8 != empty(uint256):
        result = unsafe_add(result, 1)

    if roundup and (1 << (result << 3)) < value:
        result = unsafe_add(result, 1)

    return result


@internal
@pure
def _wad_ln(x: int256) -> int256:
    """
    @dev Calculates the natural logarithm of a signed integer with a
         precision of 1e18.
    @notice Note that it returns `0` if given `0`. Furthermore, this function
            consumes about 1,400 to 1,650 gas units depending on the value
            of `x`. The implementation is inspired by Remco Bloemen's
            implementation under the MIT license here:
            https://xn--2-umb.com/22/exp-ln.
    @param x The 32-byte variable.
    @return int256 The 32-byte calculation result.
    """
    assert x >= empty(int256), "math: wad_ln undefined"

    # For the special case `x == 0`, we already return `0` here in order
    # not to iterate through the remaining code.
    if x == empty(int256):
        return empty(int256)

    # We want to convert `x` from "10**18" fixed point to "2**96"
    # fixed point. We do this by multiplying by "2**96 / 10**18".
    # But since "ln(x * C) = ln(x) + ln(C)" holds, we can just do
    # nothing here and add "ln(2**96 / 10**18)" at the end.

    # Reduce the range of `x` to "(1, 2) * 2**96".
    # Also remember that "ln(2**k * x) = k * ln(2) + ln(x)" holds.
    k: int256 = unsafe_sub(convert(self._log2(convert(x, uint256), False), int256), 96)
    # Note that to circumvent Vyper's safecast feature for the potentially
    # negative expression `x <<= uint256(159 - k)`, we first convert the
    # expression `x <<= uint256(159 - k)` to `bytes32` and subsequently
    # to `uint256`. Remember that the EVM default behaviour is to use two's
    # complement representation to handle signed integers.
    x = convert(convert(convert(x << convert(unsafe_sub(159, k), uint256), bytes32), uint256) >> 159, int256)

    # Evaluate using a "(8, 8)"-term rational approximation. Since `p` is monic,
    # we will multiply by a scaling factor later.
    p: int256 = unsafe_add(
        unsafe_mul(unsafe_add(x, 3_273_285_459_638_523_848_632_254_066_296), x) >> 96,
        24_828_157_081_833_163_892_658_089_445_524,
    )
    p = unsafe_add(unsafe_mul(p, x) >> 96, 43_456_485_725_739_037_958_740_375_743_393)
    p = unsafe_sub(unsafe_mul(p, x) >> 96, 11_111_509_109_440_967_052_023_855_526_967)
    p = unsafe_sub(unsafe_mul(p, x) >> 96, 45_023_709_667_254_063_763_336_534_515_857)
    p = unsafe_sub(unsafe_mul(p, x) >> 96, 14_706_773_417_378_608_786_704_636_184_526)
    p = unsafe_sub(unsafe_mul(p, x), 795_164_235_651_350_426_258_249_787_498 << 96)

    # We leave `p` in the "2**192" base so that we do not have to scale it up
    # again for the division. Note that `q` is monic by convention.
    q: int256 = unsafe_add(
        unsafe_mul(unsafe_add(x, 5_573_035_233_440_673_466_300_451_813_936), x) >> 96,
        71_694_874_799_317_883_764_090_561_454_958,
    )
    q = unsafe_add(unsafe_mul(q, x) >> 96, 283_447_036_172_924_575_727_196_451_306_956)
    q = unsafe_add(unsafe_mul(q, x) >> 96, 401_686_690_394_027_663_651_624_208_769_553)
    q = unsafe_add(unsafe_mul(q, x) >> 96, 204_048_457_590_392_012_362_485_061_816_622)
    q = unsafe_add(unsafe_mul(q, x) >> 96, 31_853_899_698_501_571_402_653_359_427_138)
    q = unsafe_add(unsafe_mul(q, x) >> 96, 909_429_971_244_387_300_277_376_558_375)

    # It is known that the polynomial `q` has no zeros in the domain.
    # No scaling is required, as `p` is already "2**96" too large. Also,
    # `r` is in the range "(0, 0.125) * 2**96" after the division.
    r: int256 = unsafe_div(p, q)

    # To finalise the calculation, we have to proceed with the following steps:
    #   - multiply by the scaling factor "s = 5.549...",
    #   - add "ln(2**96 / 10**18)",
    #   - add "k * ln(2)", and
    #   - multiply by "10**18 / 2**96 = 5**18 >> 78".
    # In order to perform the most gas-efficient calculation, we carry out all
    # these steps in one expression.
    return (
        unsafe_add(
            unsafe_add(
                unsafe_mul(r, 1_677_202_110_996_718_588_342_820_967_067_443_963_516_166),
                unsafe_mul(
                    k, 16_597_577_552_685_614_221_487_285_958_193_947_469_193_820_559_219_878_177_908_093_499_208_371
                ),
            ),
            600_920_179_829_731_861_736_702_779_321_621_459_595_472_258_049_074_101_567_377_883_020_018_308,
        )
        >> 174
    )


@internal
@pure
def _wad_exp(x: int256) -> int256:
    """
    @dev Calculates the natural exponential function of a signed integer with
         a precision of 1e18.
    @notice Note that this function consumes about 810 gas units. The implementation
            is inspired by Remco Bloemen's implementation under the MIT license here:
            https://xn--2-umb.com/22/exp-ln.
    @param x The 32-byte variable.
    @return int256 The 32-byte calculation result.
    """
    # If the result is `< 1`, we return zero. This happens when we have the following:
    # "x <= (log(1e-18) * 1e18) ~ -4.15e19".
    if x <= -41_446_531_673_892_822_313:
        return empty(int256)

    # When the result is "> (2**255 - 1) / 1e18" we cannot represent it as a signed integer.
    # This happens when "x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135".
    assert x < 135_305_999_368_893_231_589, "math: wad_exp overflow"

    # `x` is now in the range "(-42, 136) * 1e18". Convert to "(-42, 136) * 2**96" for higher
    # intermediate precision and a binary base. This base conversion is a multiplication with
    # "1e18 / 2**96 = 5**18 / 2**78".
    x = unsafe_div(x << 78, 5 ** 18)

    # Reduce the range of `x` to "(-½ ln 2, ½ ln 2) * 2**96" by factoring out powers of two
    # so that "exp(x) = exp(x') * 2**k", where `k` is a signer integer. Solving this gives
    # "k = round(x / log(2))" and "x' = x - k * log(2)". Thus, `k` is in the range "[-61, 195]".
    k: int256 = unsafe_add(unsafe_div(x << 96, 54_916_777_467_707_473_351_141_471_128), 2 ** 95) >> 96
    x = unsafe_sub(x, unsafe_mul(k, 54_916_777_467_707_473_351_141_471_128))

    # Evaluate using a "(6, 7)"-term rational approximation. Since `p` is monic,
    # we will multiply by a scaling factor later.
    y: int256 = unsafe_add(
        unsafe_mul(unsafe_add(x, 1_346_386_616_545_796_478_920_950_773_328), x) >> 96,
        57_155_421_227_552_351_082_224_309_758_442,
    )
    p: int256 = unsafe_add(
        unsafe_mul(
            unsafe_add(
                unsafe_mul(unsafe_sub(unsafe_add(y, x), 94_201_549_194_550_492_254_356_042_504_812), y) >> 96,
                28_719_021_644_029_726_153_956_944_680_412_240,
            ),
            x,
        ),
        4_385_272_521_454_847_904_659_076_985_693_276 << 96,
    )

    # We leave `p` in the "2**192" base so that we do not have to scale it up
    # again for the division.
    q: int256 = unsafe_add(
        unsafe_mul(unsafe_sub(x, 2_855_989_394_907_223_263_936_484_059_900), x) >> 96,
        50_020_603_652_535_783_019_961_831_881_945,
    )
    q = unsafe_sub(unsafe_mul(q, x) >> 96, 533_845_033_583_426_703_283_633_433_725_380)
    q = unsafe_add(unsafe_mul(q, x) >> 96, 3_604_857_256_930_695_427_073_651_918_091_429)
    q = unsafe_sub(unsafe_mul(q, x) >> 96, 14_423_608_567_350_463_180_887_372_962_807_573)
    q = unsafe_add(unsafe_mul(q, x) >> 96, 26_449_188_498_355_588_339_934_803_723_976_023)

    # The polynomial `q` has no zeros in the range because all its roots are complex.
    # No scaling is required, as `p` is already "2**96" too large. Also,
    # `r` is in the range "(0.09, 0.25) * 2**96" after the division.
    r: int256 = unsafe_div(p, q)

    # To finalise the calculation, we have to multiply `r` by:
    #   - the scale factor "s = ~6.031367120",
    #   - the factor "2**k" from the range reduction, and
    #   - the factor "1e18 / 2**96" for the base conversion.
    # We do this all at once, with an intermediate result in "2**213" base,
    # so that the final right shift always gives a positive value.

    # Note that to circumvent Vyper's safecast feature for the potentially
    # negative parameter value `r`, we first convert `r` to `bytes32` and
    # subsequently to `uint256`. Remember that the EVM default behaviour is
    # to use two's complement representation to handle signed integers.
    return convert(
        unsafe_mul(
            convert(convert(r, bytes32), uint256), 3_822_833_074_963_236_453_042_738_258_902_158_003_155_416_615_667
        )
        >> convert(unsafe_sub(195, k), uint256),
        int256,
    )


@internal
@pure
def _cbrt(x: uint256, roundup: bool) -> uint256:
    """
    @dev Calculates the cube root of an unsigned integer.
    @notice Note that this function consumes about 1,600 to 1,800 gas units
            depending on the value of `x` and `roundup`. The implementation is
            inspired by Curve Finance's implementation under the MIT license here:
            https://github.com/curvefi/tricrypto-ng/blob/main/contracts/main/CurveCryptoMathOptimized3.vy.
    @param x The 32-byte variable from which the cube root is calculated.
    @param roundup The Boolean variable that specifies whether
           to round up or not. The default `False` is round down.
    @return The 32-byte cube root of `x`.
    """
    # For the special case `x == 0`, we already return `0` here in order
    # not to iterate through the remaining code.
    if x == empty(uint256):
        return empty(uint256)

    y: uint256 = unsafe_div(self._wad_cbrt(x), 10 ** 12)

    if roundup and unsafe_mul(unsafe_mul(y, y), y) != x:
        y = unsafe_add(y, 1)

    return y


@internal
@pure
def _wad_cbrt(x: uint256) -> uint256:
    """
    @dev Calculates the cube root of an unsigned integer with a precision
         of 1e18.
    @notice Note that this function consumes about 1,500 to 1,700 gas units
            depending on the value of `x`. The implementation is inspired
            by Curve Finance's implementation under the MIT license here:
            https://github.com/curvefi/tricrypto-ng/blob/main/contracts/main/CurveCryptoMathOptimized3.vy.
    @param x The 32-byte variable from which the cube root is calculated.
    @return The 32-byte cubic root of `x` with a precision of 1e18.
    """
    # For the special case `x == 0`, we already return `0` here in order
    # not to iterate through the remaining code.
    if x == empty(uint256):
        return empty(uint256)

    # Since this cube root is for numbers with base 1e18, we have to scale
    # the input by 1e36 to increase the precision. This leads to an overflow
    # for very large numbers. So we conditionally sacrifice precision.
    value: uint256 = empty(uint256)
    if x >= unsafe_mul(unsafe_div(max_value(uint256), 10 ** 36), 10 ** 18):
        value = x
    elif x >= unsafe_div(max_value(uint256), 10 ** 36):
        value = unsafe_mul(x, 10 ** 18)
    else:
        value = unsafe_mul(x, 10 ** 36)

    # Compute the binary logarithm of `value`.
    log2x: uint256 = self._log2(value, False)

    # If we divide log2x by 3, the remainder is "log2x % 3". So if we simply
    # multiply "2**(log2x/3)" and discard the remainder to calculate our guess,
    # the Newton-Raphson method takes more iterations to converge to a solution
    # because it lacks this precision. A few more calculations now in order to
    # do fewer calculations later:
    #   - "pow = log2(x) // 3" (the operator `//` means integer division),
    #   - "remainder = log2(x) % 3",
    #   - "initial_guess = 2**pow * cbrt(2)**remainder".
    # Now substituting "2 = 1.26 ≈ 1,260 / 1,000", we get:
    #   - "initial_guess = 2**pow * 1,260**remainder // 1,000**remainder".
    remainder: uint256 = log2x % 3
    y: uint256 = unsafe_div(
        unsafe_mul(pow_mod256(2, unsafe_div(log2x, 3)), pow_mod256(1_260, remainder)), pow_mod256(1_000, remainder)
    )

    # Since we have chosen good initial values for the cube roots, 7 Newton-Raphson
    # iterations are just sufficient. 6 iterations would lead to non-convergences,
    # and 8 would be one iteration too many. Without initial values, the iteration
    # number can be up to 20 or more. The iterations are unrolled. This reduces the
    # gas cost, but requires more bytecode.
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)
    y = unsafe_div(unsafe_add(unsafe_mul(2, y), unsafe_div(value, unsafe_mul(y, y))), 3)

    # Since we scaled up, we have to scale down accordingly.
    if x >= unsafe_mul(unsafe_div(max_value(uint256), 10 ** 36), 10 ** 18):
        return unsafe_mul(y, 10 ** 12)
    elif x >= unsafe_div(max_value(uint256), 10 ** 36):
        return unsafe_mul(y, 10 ** 6)

    return y

Settings
{
  "outputSelection": {
    "contracts/AMM.vy": [
      "evm.bytecode",
      "evm.deployedBytecode",
      "abi"
    ]
  },
  "search_paths": [
    ".venv/lib/pypy3.11/site-packages",
    "."
  ]
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"name":"buyer","type":"address"},{"indexed":false,"name":"sold_id","type":"uint256"},{"indexed":false,"name":"tokens_sold","type":"uint256"},{"indexed":false,"name":"bought_id","type":"uint256"},{"indexed":false,"name":"tokens_bought","type":"uint256"},{"indexed":false,"name":"fee","type":"uint256"},{"indexed":false,"name":"price_oracle","type":"uint256"}],"name":"TokenExchange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token_amounts","type":"uint256[2]"},{"indexed":false,"name":"invariant","type":"uint256"},{"indexed":false,"name":"price_oracle","type":"uint256"}],"name":"AddLiquidityRaw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"collateral_change","type":"uint256"},{"indexed":false,"name":"debt_change","type":"uint256"}],"name":"RemoveLiquidityRaw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"rate","type":"uint256"},{"indexed":false,"name":"rate_mul","type":"uint256"},{"indexed":false,"name":"time","type":"uint256"}],"name":"SetRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"new_supply","type":"uint256"}],"name":"CollectFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fee","type":"uint256"}],"name":"SetFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"is_killed","type":"bool"}],"name":"SetKilled","type":"event"},{"inputs":[],"name":"get_rate_mul","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"rate","type":"uint256"}],"name":"set_rate","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"get_debt","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"outdated_debt","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_state","outputs":[{"components":[{"name":"collateral","type":"uint256"},{"name":"debt","type":"uint256"},{"name":"x0","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"},{"name":"in_amount","type":"uint256"}],"name":"get_dy","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_p","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"},{"name":"in_amount","type":"uint256"},{"name":"min_out","type":"uint256"}],"name":"exchange","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"},{"name":"in_amount","type":"uint256"},{"name":"min_out","type":"uint256"},{"name":"_for","type":"address"}],"name":"exchange","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"d_collateral","type":"uint256"},{"name":"d_debt","type":"uint256"}],"name":"_deposit","outputs":[{"components":[{"name":"p_o","type":"uint256"},{"name":"value","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"frac","type":"uint256"}],"name":"_withdraw","outputs":[{"components":[{"name":"collateral","type":"uint256"},{"name":"debt","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"i","type":"uint256"}],"name":"coins","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"value_oracle","outputs":[{"components":[{"name":"p_o","type":"uint256"},{"name":"value","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"collateral","type":"uint256"},{"name":"debt","type":"uint256"}],"name":"value_oracle_for","outputs":[{"components":[{"name":"p_o","type":"uint256"},{"name":"value","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"collateral_amount","type":"uint256"},{"name":"borrowed_amount","type":"uint256"},{"name":"is_deposit","type":"bool"}],"name":"value_change","outputs":[{"components":[{"name":"p_o","type":"uint256"},{"name":"value","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"max_debt","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accumulated_interest","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collect_fees","outputs":[{"name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"is_killed","type":"bool"}],"name":"set_killed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"check_nonreentrant","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"name":"fee","type":"uint256"}],"name":"set_fee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"LEVERAGE","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LT_CONTRACT","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COLLATERAL","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STABLECOIN","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_ORACLE_CONTRACT","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral_amount","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rate","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rate_mul","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minted","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemed","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"is_killed","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"lt_contract","type":"address"},{"name":"stablecoin","type":"address"},{"name":"collateral","type":"address"},{"name":"leverage","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"price_oracle_contract","type":"address"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"}]

0x6122455150346104ee5760206126705f395f518060a01c6104ee5760405260206126905f395f518060a01c6104ee5760605260206126b05f395f518060a01c6104ee5760805260206127105f395f518060a01c6104ee5760a0526040516121c552606051612205526080516121e55260206126d05f395f516121455267016345785d8a000060206126f05f395f5111156101085760208061012052600c60c0527f46656520746f6f2068696768000000000000000000000000000000000000000060e05260c08161012001602c82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b60206126f05f395f515f5560a051612225526121e55163313ce56760c052602060c0600460dc845afa61013d573d5f5f3e3d5ffd5b60203d106104ee5760c090505180601203601281116104ee579050604d81116104ee5780600a0a90506122455260126122055163313ce56760c052602060c0600460dc845afa61018f573d5f5f3e3d5ffd5b60203d106104ee5760c0905051186104ee57670de0b6b3a764000160206126d05f395f51106104ee5760206126d05f395f518060011b818160011c186104ee579050670de0b6b3a764000081038181116104ee57905060c05260206126d05f395f516fffffffffffffffffffffffffffffffff81116104ee576002810a9050670de0b6b3a7640000810281670de0b6b3a76400008204186104ee57905060c0516fffffffffffffffffffffffffffffffff81116104ee576002810a905080156104ee57808204905090506121655260206126d05f395f516fffffffffffffffffffffffffffffffff81116104ee576002810a90508060021b818160021c186104ee57905080156104ee5780760a70c3c40a64e6c51999090b65f67d92400000000000000490506121855260c0516fffffffffffffffffffffffffffffffff81116104ee576002810a9050670de0b6b3a7640000810281670de0b6b3a76400008204186104ee57905060206126d05f395f516fffffffffffffffffffffffffffffffff81116104ee576002810a90508060021b818160021c186104ee57905080156104ee578082049050905060206126d05f395f516fffffffffffffffffffffffffffffffff81116104ee576002810a90508060031b818160031c186104ee57905080156104ee5780760a70c3c40a64e6c51999090b65f67d92400000000000000490508082038281116104ee57905090506121a552670de0b6b3a76400006004554260055560605163095ea7b360e0526121c551610100527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61012052602060e0604460fc5f855af1610404573d5f5f3e3d5ffd5b3d61041b57803b156104ee57600161014052610443565b3d602081183d60201002188060e001610100116104ee5760e0518060011c6104ee5761014052505b610140505060805163095ea7b360e0526121c551610100527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61012052602060e0604460fc5f855af1610498573d5f5f3e3d5ffd5b3d6104af57803b156104ee576001610140526104d7565b3d602081183d60201002188060e001610100116104ee5760e0518060011c6104ee5761014052505b61014050506121456104f261000039612265610000f35b5f80fd5f3560e01c6002601d820660011b61210b01601e395f51565b63095a0fc68118611a1457346121075760206100346040611a18565b6040f35b63d4387a998118611a1457602436103417612107575f5c6001146121075760015f5d60206121c55f395f513318156100db5760208060a05260066040527f416363657373000000000000000000000000000000000000000000000000000060605260408160a001602682825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b6407620d06ef600435111561015b5760208060a052600d6040527f5261746520746f6f20686967680000000000000000000000000000000000000060605260408160a001602d82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b6101656060611a18565b606051604052600254604051808202811583838304141715612107579050905060045480156121075780820490509050600255604051600455426005556004356003557f52543716810f73c3fa9bca74622aecb6d3614ca4991472f3e999d531c2f6afb86004356060526040516080524260a05260606060a1602060405f5f5df35b630b576c96811861020757346121075760206102036060611a83565b6060f35b63c6610657811861024557602436103417612107576020602061220560403960206121e5606039604060043560028110156121075760051b81019050f35b638d01f0ba8118611a14573461210757602061214560403960206040f35b638d96b618811861027f57346121075760025460405260206040f35b630469c157811861029a5734612107575f5c60011461210757005b63ddca3f438118611a145734612107575f5460405260206040f35b6386b301ad811861034957346121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa6102f0573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526060366101e0376001546101e05261031b610240611a83565b610240516102005260606101c060605e5f60c05261033a610240611ba4565b610240516102205260606101e0f35b632c4e722e811861036557346121075760035460405260206040f35b634f02c4208118611a1457346121075760065460405260206040f35b63556d6e9f811861064c57606436103417612107576004356103a957600160243518156103ab565b5f5b6103c8576001600435186103c257602435156103cb565b5f6103cb565b60015b156121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa6103fb573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e05261041f610220611a83565b610220516102005260606101c060605e5f60c05261043e610240611ba4565b6102405161020051808203828111612107579050905061022052600435610599576102005160443511156104e4576020806102a0526010610240527f416d6f756e7420746f6f206c617267650000000000000000000000000000000061026052610240816102a001603082825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610280528060040161029cfd5b61022051604435808201828110612107579050905061024052610220516101e05180820281158383830414171561210757905090506040526102405160605261052e610280611e45565b61028051610260526101e0516102605180820382811161210757905090505f5480670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a76400008104905061028052602061028061064a565b6101e051604435808201828110612107579050905061024052610220516101e0518082028115838383041417156121075790509050604052610240516060526105e3610280611e45565b6102805161026052610220516102605180820382811161210757905090505f5480670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a7640000810490506102805260206102805bf35b63bbbf46a18118611a14576044361034176121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa61068c573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526101c051610200526101c051606052604060046080375f60c0526106c36101e0611ba4565b6101e051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610220526040610200f35b63f2388acb811861080a57346121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa610765573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e052610789610220611a83565b610220516102005260606101c060605e5f60c0526107a8610220611ba4565b6102205161020051808203828111612107579050905060206122455f395f5180156121075780670de0b6b3a764000004905080820281158383830414171561210757905090506101e05180156121075780820490509050610240526020610240f35b63a3cd68058118611a1457346121075760206121c560403960206040f35b635b41b90881186108475760843610341761210757336101c052610945565b631aa02d598118611a14576024361034176121075760206121c55f395f513318156108dd5760208060a05260066040527f416363657373000000000000000000000000000000000000000000000000000060605260408160a001602682825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b67016345785d8a000060043511612107576004355f557e172ddfc5ae88d08b3de01a5a187667c37a5a53989e8c175055cb6c993792a760043560405260206040a1005b63a64833a08118611a145760a436103417612107576084358060a01c612107576101c0525b5f5c6001146121075760015f5d6004356109655760016024351815610967565b5f5b6109845760016004351861097e5760243515610987565b5f610987565b60015b1561210757600854612107576001546101e0526101e051610a1a57602080610260526009610200527f456d70747920414d4d0000000000000000000000000000000000000000000000610220526102008161026001602982825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610240528060040161025cfd5b610a25610220611ee7565b610220516102005260206122255f395f5163ceb7f759610240526020610240600461025c5f855af1610a59573d5f5f3e3d5ffd5b60203d106121075761024090505161022052610220516060526101e0516080526102005160a0525f60c052610a8f610260611ba4565b610260516102405261024051610200518082038281116121075790509050610260525f610280525f546102a052600435610d55576102605160443580820182811061210757905090506102c052610260516101e05180820281158383830414171561210757905090506040526102c051606052610b0d610300611e45565b610300516102e0526101e0516102e05180820382811161210757905090506102a05180670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a76400008104905061028052606435610280511015610bf557602080610360526008610300527f536c697070616765000000000000000000000000000000000000000000000000610320526103008161036001602882825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610340528060040161035cfd5b610200516044358082038281116121075790509050610200526101e0516102805180820382811161210757905090506101e052600754604435808201828110612107579050905060075560206122055f395f516323b872dd6103005233610320523061034052604435610360526020610300606461031c5f855af1610c7c573d5f5f3e3d5ffd5b3d610c9357803b1561210757600161038052610cbd565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761038052505b610380905051156121075760206121e55f395f5163a9059cbb610300526101c0516103205261028051610340526020610300604461031c5f855af1610d04573d5f5f3e3d5ffd5b3d610d1b57803b1561210757600161036052610d45565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761036052505b6103609050511561210757610fd3565b6101e05160443580820182811061210757905090506102c052610260516101e05180820281158383830414171561210757905090506040526102c051606052610d9f610300611e45565b610300516102e052610260516102e05180820382811161210757905090506102a05180670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a76400008104905061028052606435610280511015610e8757602080610360526008610300527f536c697070616765000000000000000000000000000000000000000000000000610320526103008161036001602882825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610340528060040161035cfd5b61020051610280518082018281106121075790509050610200526006546102805180820182811061210757905090506006556102c0516101e05260206121e55f395f516323b872dd6103005233610320523061034052604435610360526020610300606461031c5f855af1610efe573d5f5f3e3d5ffd5b3d610f1557803b1561210757600161038052610f3f565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761038052505b610380905051156121075760206122055f395f5163a9059cbb610300526101c0516103205261028051610340526020610300604461031c5f855af1610f86573d5f5f3e3d5ffd5b3d610f9d57803b1561210757600161036052610fc7565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761036052505b61036090505115612107575b61024051610220516060526101e0516080526102005160a052600160c052610ffc6102c0611ba4565b6102c051101561107e5760208061034052600f6102e0527f4261642066696e616c2073746174650000000000000000000000000000000000610300526102e08161034001602f82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610320528060040161033cfd5b6101e05160015561020051600255337f143f1f8e861fbdeddd5b46e844b7d3ac7b86a122f36e8c463859ee6811b1f29c6004356102c0526044356102e0526024356103005260406102806103205e610220516103605260c06102c0a260206121c55f395f51156110f95760206121c55f395f513b15156110fb565b5f5b156111435761110b6102c0611f36565b6102c05060206121c55f395f51637ba3152e6102c052803b15612107575f6102c060046102dc5f855af1611141573d5f5f3e3d5ffd5b505b60206102805f5f5df35b63f3207723811861136e576044361034176121075760206121c55f395f513318156111ea576020806102205260106101c0527f4163636573732076696f6c6174696f6e000000000000000000000000000000006101e0526101c08161022001603082825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610200528060040161021cfd5b6008546121075760206122255f395f5163ceb7f7596101e05260206101e060046101fc5f855af161121d573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e052611241610220611ee7565b6102205161020052610200516024358082018281106121075790509050610200526101e05160043580820182811061210757905090506101e0526006546024358082018281106121075790509050600655610200516002556101e05160015560606101c060605e600160c0526112b8610240611ba4565b61024051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610220527f488e5334cc9bea5219087037712837bf3d72b260676f5d41c866905cca6842d1604060046102403761022051610280526101c0516102a0526080610240a16101c0516102405261022051610260526040610240f35b635ef7feab8118611a1457346121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa6113a9573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e0526113cd610220611a83565b61022051610200526101c0516102405260606101c060605e5f60c0526113f4610220611ba4565b61022051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610260526040610240f35b63ac6a2b5d8118611a14576024361034176121075760206121c55f395f513318156114f8576020806101a0526010610140527f4163636573732076696f6c6174696f6e0000000000000000000000000000000061016052610140816101a001603082825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b6001546101405261150a610180611ee7565b6101805161016052610140516004358082028115838383041417156121075790509050670de0b6b3a76400008104905061018052610160516004358082028115838383041417156121075790509050604052670de0b6b3a76400006060526115736101c0611e45565b6101c0516101a052600154610180518082038281116121075790509050600155610160516101a05180820382811161210757905090506002556007546101a05180820182811061210757905090506007557f33c707093baa929b1d0237d3c8111e597ba833fcc950696c87d5ff66a287e31e60406101806101c05e60406101c0a160406101806101c05e60406101c0f35b63059eaa788118611a1457606436103417612107576044358060011c612107576101c05260206122255f395f5163a035b1fe610200526020610200600461021c845afa611653573d5f5f3e3d5ffd5b60203d10612107576102009050516101e05260015461020052611677610240611a83565b61024051610220526101c0516116be5761020051600435808203828111612107579050905061020052610220516024358082038281116121075790509050610220526116f1565b61020051600435808201828110612107579050905061020052610220516024358082018281106121075790509050610220525b60606101e060605e6101c05160c05261170b610260611ba4565b61026051610240526101e0516102605261024051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610280526040610260f35b63638a1e8d81186117ef57346121075760206122055f395f516370a0823160605230608052602060606024607c845afa6117be573d5f5f3e3d5ffd5b60203d106121075760609050516117d560a0611a83565b60a051808201828110612107579050905060c052602060c0f35b6393a39776811861180d573461210757602061220560403960206040f35b639c868ac08118611a1457346121075760085460405260206040f35b63dbe57fe88118611a1457346121075760065460605260605161184c6080611a83565b6080516007548082018281106121075790509050606051808281188284110218905090500360a052602060a0f35b631e0cfcef8118611a145734612107575f5c6001146121075760015f5d60206118a4610180611f36565b6101805f5f5df35b6390b229978118611a1457602436103417612107576004358060011c6121075760405260206121c55f395f513318156119505760208060c05260066060527f416363657373000000000000000000000000000000000000000000000000000060805260608160c001602682825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060a0528060040160bcfd5b6040516008557ff6a23ecf31263066d4cc1ac21837c1714818045ecc5c0dd89f279e0bd4b7ef8760405160605260206060a1005b6324bbab8b8118611a1457346121075760206121e560403960206040f35b6378f5e9f08118611a14573461210757602061222560403960206040f35b63e0f038e78118611a1457346121075760015460405260206040f35b63d25028b88118611a1457346121075760045460405260206040f35b63e231bff08118611a1457346121075760075460405260206040f35b5f5ffd5b670de0b6b3a7640000600454600354426005548082038281116121075790509050808202811583838304141715612107579050905080670de0b6b3a764000001670de0b6b3a76400008110612107579050808202811583838304141715612107579050905004815250565b600254611a906040611a18565b604051808202811583838304141715612107579050905060045480156121075780820490509050815250565b6040518060b5710100000000000000000000000000000000008210611ae8578160801c91508060401b90505b69010000000000000000008210611b06578160401c91508060201b90505b650100000000008210611b20578160201c91508060101b90505b63010000008210611b38578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c90508083048082811882841002189050905090509050815250565b606051608051808202811583838304141715612107579050905060206122455f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060e05260c05115611d4f5760e05160206121855f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060a0511015611ca15760208061016052600a610100527f556e73616665206d696e00000000000000000000000000000000000000000000610120526101008161016001602a82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610140528060040161015cfd5b60e05160206121a55f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060a0511115611d4f5760208061016052600a610100527f556e73616665206d617800000000000000000000000000000000000000000000610120526101008161016001602a82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610140528060040161015cfd5b60e0516fffffffffffffffffffffffffffffffff8111612107576002810a905060e0518060021b818160021c1861210757905060206121655f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060a051808202811583838304141715612107579050905080820382811161210757905090506101005260e05161010051604052611dea610120611abc565b610120518082018281106121075790509050670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121655f395f518060011b818160011c1861210757905080156121075780820490509050815250565b606051611ebd5760208060e052601f6080527f6d6174683a206365696c5f646976206469766973696f6e206279207a65726f0060a05260808160e001603f82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b604051611eca575f611ee2565b60016060516040516001810381811161210757905004015b815250565b611ef16060611a18565b60605160405260025460405180820281158383830414171561210757905090506004548015612107578082049050905060605260405160045542600555606051815250565b60085461210757611f4760a0611ee7565b60a05160805260805160025560065460a052608051600754808201828110612107579050905060c05260a05160c05111611fb5577f5393ab6ef9bb40d91d1b04bbbeb707fbf3d1eb73f46744e2d179e4996026283f5f60e05260805161010052604060e0a15f815250612105565b60c05160065560a05160c0510360c05260206122055f395f516370a082316101005230610120526020610100602461011c845afa611ff5573d5f5f3e3d5ffd5b60203d106121075761010090505160e05260c05160e05110156120415760065460c05160e0518082038281116121075790509050808203828111612107579050905060065560e05160c0525b60206122055f395f5163a9059cbb6101005260206121c56101203960c051610140526020610100604461011c5f855af161207d573d5f5f3e3d5ffd5b3d61209457803b15612107576001610160526120be565b3d602081183d602010021880610100016101201161210757610100518060011c6121075761016052505b61016090505115612107577f5393ab6ef9bb40d91d1b04bbbeb707fbf3d1eb73f46744e2d179e4996026283f60c05161010052608051610120526040610100a160c0518152505b565b5f80fd0263001819a2038101e708281a1419dc09201a141984072a1a1419f8160402b518291a141a141a1419c000381a14145b187a114d18ac17821a148558200ea77512631b070fc04cdb45a2e0a131fecf1684e4f6bb92f88d1a5c02b0fd5019214581183a190120a1657679706572830004030039000000000000000000000000d6a1147666f6e4d7161caf436d9923d44d901112000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e00000000000000000000000083f24023d15d835a213df24fd309c47dab5beb320000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000020af59ebef00000000000000000000000000003e5a6c61488de85383fb0efd8c152d3e10c6bfe6

Deployed Bytecode

0x5f3560e01c6002601d820660011b61210b01601e395f51565b63095a0fc68118611a1457346121075760206100346040611a18565b6040f35b63d4387a998118611a1457602436103417612107575f5c6001146121075760015f5d60206121c55f395f513318156100db5760208060a05260066040527f416363657373000000000000000000000000000000000000000000000000000060605260408160a001602682825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b6407620d06ef600435111561015b5760208060a052600d6040527f5261746520746f6f20686967680000000000000000000000000000000000000060605260408160a001602d82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b6101656060611a18565b606051604052600254604051808202811583838304141715612107579050905060045480156121075780820490509050600255604051600455426005556004356003557f52543716810f73c3fa9bca74622aecb6d3614ca4991472f3e999d531c2f6afb86004356060526040516080524260a05260606060a1602060405f5f5df35b630b576c96811861020757346121075760206102036060611a83565b6060f35b63c6610657811861024557602436103417612107576020602061220560403960206121e5606039604060043560028110156121075760051b81019050f35b638d01f0ba8118611a14573461210757602061214560403960206040f35b638d96b618811861027f57346121075760025460405260206040f35b630469c157811861029a5734612107575f5c60011461210757005b63ddca3f438118611a145734612107575f5460405260206040f35b6386b301ad811861034957346121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa6102f0573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526060366101e0376001546101e05261031b610240611a83565b610240516102005260606101c060605e5f60c05261033a610240611ba4565b610240516102205260606101e0f35b632c4e722e811861036557346121075760035460405260206040f35b634f02c4208118611a1457346121075760065460405260206040f35b63556d6e9f811861064c57606436103417612107576004356103a957600160243518156103ab565b5f5b6103c8576001600435186103c257602435156103cb565b5f6103cb565b60015b156121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa6103fb573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e05261041f610220611a83565b610220516102005260606101c060605e5f60c05261043e610240611ba4565b6102405161020051808203828111612107579050905061022052600435610599576102005160443511156104e4576020806102a0526010610240527f416d6f756e7420746f6f206c617267650000000000000000000000000000000061026052610240816102a001603082825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610280528060040161029cfd5b61022051604435808201828110612107579050905061024052610220516101e05180820281158383830414171561210757905090506040526102405160605261052e610280611e45565b61028051610260526101e0516102605180820382811161210757905090505f5480670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a76400008104905061028052602061028061064a565b6101e051604435808201828110612107579050905061024052610220516101e0518082028115838383041417156121075790509050604052610240516060526105e3610280611e45565b6102805161026052610220516102605180820382811161210757905090505f5480670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a7640000810490506102805260206102805bf35b63bbbf46a18118611a14576044361034176121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa61068c573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526101c051610200526101c051606052604060046080375f60c0526106c36101e0611ba4565b6101e051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610220526040610200f35b63f2388acb811861080a57346121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa610765573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e052610789610220611a83565b610220516102005260606101c060605e5f60c0526107a8610220611ba4565b6102205161020051808203828111612107579050905060206122455f395f5180156121075780670de0b6b3a764000004905080820281158383830414171561210757905090506101e05180156121075780820490509050610240526020610240f35b63a3cd68058118611a1457346121075760206121c560403960206040f35b635b41b90881186108475760843610341761210757336101c052610945565b631aa02d598118611a14576024361034176121075760206121c55f395f513318156108dd5760208060a05260066040527f416363657373000000000000000000000000000000000000000000000000000060605260408160a001602682825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b67016345785d8a000060043511612107576004355f557e172ddfc5ae88d08b3de01a5a187667c37a5a53989e8c175055cb6c993792a760043560405260206040a1005b63a64833a08118611a145760a436103417612107576084358060a01c612107576101c0525b5f5c6001146121075760015f5d6004356109655760016024351815610967565b5f5b6109845760016004351861097e5760243515610987565b5f610987565b60015b1561210757600854612107576001546101e0526101e051610a1a57602080610260526009610200527f456d70747920414d4d0000000000000000000000000000000000000000000000610220526102008161026001602982825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610240528060040161025cfd5b610a25610220611ee7565b610220516102005260206122255f395f5163ceb7f759610240526020610240600461025c5f855af1610a59573d5f5f3e3d5ffd5b60203d106121075761024090505161022052610220516060526101e0516080526102005160a0525f60c052610a8f610260611ba4565b610260516102405261024051610200518082038281116121075790509050610260525f610280525f546102a052600435610d55576102605160443580820182811061210757905090506102c052610260516101e05180820281158383830414171561210757905090506040526102c051606052610b0d610300611e45565b610300516102e0526101e0516102e05180820382811161210757905090506102a05180670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a76400008104905061028052606435610280511015610bf557602080610360526008610300527f536c697070616765000000000000000000000000000000000000000000000000610320526103008161036001602882825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610340528060040161035cfd5b610200516044358082038281116121075790509050610200526101e0516102805180820382811161210757905090506101e052600754604435808201828110612107579050905060075560206122055f395f516323b872dd6103005233610320523061034052604435610360526020610300606461031c5f855af1610c7c573d5f5f3e3d5ffd5b3d610c9357803b1561210757600161038052610cbd565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761038052505b610380905051156121075760206121e55f395f5163a9059cbb610300526101c0516103205261028051610340526020610300604461031c5f855af1610d04573d5f5f3e3d5ffd5b3d610d1b57803b1561210757600161036052610d45565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761036052505b6103609050511561210757610fd3565b6101e05160443580820182811061210757905090506102c052610260516101e05180820281158383830414171561210757905090506040526102c051606052610d9f610300611e45565b610300516102e052610260516102e05180820382811161210757905090506102a05180670de0b6b3a764000003670de0b6b3a764000081116121075790508082028115838383041417156121075790509050670de0b6b3a76400008104905061028052606435610280511015610e8757602080610360526008610300527f536c697070616765000000000000000000000000000000000000000000000000610320526103008161036001602882825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610340528060040161035cfd5b61020051610280518082018281106121075790509050610200526006546102805180820182811061210757905090506006556102c0516101e05260206121e55f395f516323b872dd6103005233610320523061034052604435610360526020610300606461031c5f855af1610efe573d5f5f3e3d5ffd5b3d610f1557803b1561210757600161038052610f3f565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761038052505b610380905051156121075760206122055f395f5163a9059cbb610300526101c0516103205261028051610340526020610300604461031c5f855af1610f86573d5f5f3e3d5ffd5b3d610f9d57803b1561210757600161036052610fc7565b3d602081183d602010021880610300016103201161210757610300518060011c6121075761036052505b61036090505115612107575b61024051610220516060526101e0516080526102005160a052600160c052610ffc6102c0611ba4565b6102c051101561107e5760208061034052600f6102e0527f4261642066696e616c2073746174650000000000000000000000000000000000610300526102e08161034001602f82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610320528060040161033cfd5b6101e05160015561020051600255337f143f1f8e861fbdeddd5b46e844b7d3ac7b86a122f36e8c463859ee6811b1f29c6004356102c0526044356102e0526024356103005260406102806103205e610220516103605260c06102c0a260206121c55f395f51156110f95760206121c55f395f513b15156110fb565b5f5b156111435761110b6102c0611f36565b6102c05060206121c55f395f51637ba3152e6102c052803b15612107575f6102c060046102dc5f855af1611141573d5f5f3e3d5ffd5b505b60206102805f5f5df35b63f3207723811861136e576044361034176121075760206121c55f395f513318156111ea576020806102205260106101c0527f4163636573732076696f6c6174696f6e000000000000000000000000000000006101e0526101c08161022001603082825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610200528060040161021cfd5b6008546121075760206122255f395f5163ceb7f7596101e05260206101e060046101fc5f855af161121d573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e052611241610220611ee7565b6102205161020052610200516024358082018281106121075790509050610200526101e05160043580820182811061210757905090506101e0526006546024358082018281106121075790509050600655610200516002556101e05160015560606101c060605e600160c0526112b8610240611ba4565b61024051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610220527f488e5334cc9bea5219087037712837bf3d72b260676f5d41c866905cca6842d1604060046102403761022051610280526101c0516102a0526080610240a16101c0516102405261022051610260526040610240f35b635ef7feab8118611a1457346121075760206122255f395f5163a035b1fe6101e05260206101e060046101fc845afa6113a9573d5f5f3e3d5ffd5b60203d10612107576101e09050516101c0526001546101e0526113cd610220611a83565b61022051610200526101c0516102405260606101c060605e5f60c0526113f4610220611ba4565b61022051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610260526040610240f35b63ac6a2b5d8118611a14576024361034176121075760206121c55f395f513318156114f8576020806101a0526010610140527f4163636573732076696f6c6174696f6e0000000000000000000000000000000061016052610140816101a001603082825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b6001546101405261150a610180611ee7565b6101805161016052610140516004358082028115838383041417156121075790509050670de0b6b3a76400008104905061018052610160516004358082028115838383041417156121075790509050604052670de0b6b3a76400006060526115736101c0611e45565b6101c0516101a052600154610180518082038281116121075790509050600155610160516101a05180820382811161210757905090506002556007546101a05180820182811061210757905090506007557f33c707093baa929b1d0237d3c8111e597ba833fcc950696c87d5ff66a287e31e60406101806101c05e60406101c0a160406101806101c05e60406101c0f35b63059eaa788118611a1457606436103417612107576044358060011c612107576101c05260206122255f395f5163a035b1fe610200526020610200600461021c845afa611653573d5f5f3e3d5ffd5b60203d10612107576102009050516101e05260015461020052611677610240611a83565b61024051610220526101c0516116be5761020051600435808203828111612107579050905061020052610220516024358082038281116121075790509050610220526116f1565b61020051600435808201828110612107579050905061020052610220516024358082018281106121075790509050610220525b60606101e060605e6101c05160c05261170b610260611ba4565b61026051610240526101e0516102605261024051670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121455f395f518060011b818160011c18612107579050670de0b6b3a7640000810381811161210757905080156121075780820490509050610280526040610260f35b63638a1e8d81186117ef57346121075760206122055f395f516370a0823160605230608052602060606024607c845afa6117be573d5f5f3e3d5ffd5b60203d106121075760609050516117d560a0611a83565b60a051808201828110612107579050905060c052602060c0f35b6393a39776811861180d573461210757602061220560403960206040f35b639c868ac08118611a1457346121075760085460405260206040f35b63dbe57fe88118611a1457346121075760065460605260605161184c6080611a83565b6080516007548082018281106121075790509050606051808281188284110218905090500360a052602060a0f35b631e0cfcef8118611a145734612107575f5c6001146121075760015f5d60206118a4610180611f36565b6101805f5f5df35b6390b229978118611a1457602436103417612107576004358060011c6121075760405260206121c55f395f513318156119505760208060c05260066060527f416363657373000000000000000000000000000000000000000000000000000060805260608160c001602682825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060a0528060040160bcfd5b6040516008557ff6a23ecf31263066d4cc1ac21837c1714818045ecc5c0dd89f279e0bd4b7ef8760405160605260206060a1005b6324bbab8b8118611a1457346121075760206121e560403960206040f35b6378f5e9f08118611a14573461210757602061222560403960206040f35b63e0f038e78118611a1457346121075760015460405260206040f35b63d25028b88118611a1457346121075760045460405260206040f35b63e231bff08118611a1457346121075760075460405260206040f35b5f5ffd5b670de0b6b3a7640000600454600354426005548082038281116121075790509050808202811583838304141715612107579050905080670de0b6b3a764000001670de0b6b3a76400008110612107579050808202811583838304141715612107579050905004815250565b600254611a906040611a18565b604051808202811583838304141715612107579050905060045480156121075780820490509050815250565b6040518060b5710100000000000000000000000000000000008210611ae8578160801c91508060401b90505b69010000000000000000008210611b06578160401c91508060201b90505b650100000000008210611b20578160201c91508060101b90505b63010000008210611b38578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c90508083048082811882841002189050905090509050815250565b606051608051808202811583838304141715612107579050905060206122455f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060e05260c05115611d4f5760e05160206121855f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060a0511015611ca15760208061016052600a610100527f556e73616665206d696e00000000000000000000000000000000000000000000610120526101008161016001602a82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610140528060040161015cfd5b60e05160206121a55f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060a0511115611d4f5760208061016052600a610100527f556e73616665206d617800000000000000000000000000000000000000000000610120526101008161016001602a82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610140528060040161015cfd5b60e0516fffffffffffffffffffffffffffffffff8111612107576002810a905060e0518060021b818160021c1861210757905060206121655f395f518082028115838383041417156121075790509050670de0b6b3a76400008104905060a051808202811583838304141715612107579050905080820382811161210757905090506101005260e05161010051604052611dea610120611abc565b610120518082018281106121075790509050670de0b6b3a7640000810281670de0b6b3a764000082041861210757905060206121655f395f518060011b818160011c1861210757905080156121075780820490509050815250565b606051611ebd5760208060e052601f6080527f6d6174683a206365696c5f646976206469766973696f6e206279207a65726f0060a05260808160e001603f82825e8051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b604051611eca575f611ee2565b60016060516040516001810381811161210757905004015b815250565b611ef16060611a18565b60605160405260025460405180820281158383830414171561210757905090506004548015612107578082049050905060605260405160045542600555606051815250565b60085461210757611f4760a0611ee7565b60a05160805260805160025560065460a052608051600754808201828110612107579050905060c05260a05160c05111611fb5577f5393ab6ef9bb40d91d1b04bbbeb707fbf3d1eb73f46744e2d179e4996026283f5f60e05260805161010052604060e0a15f815250612105565b60c05160065560a05160c0510360c05260206122055f395f516370a082316101005230610120526020610100602461011c845afa611ff5573d5f5f3e3d5ffd5b60203d106121075761010090505160e05260c05160e05110156120415760065460c05160e0518082038281116121075790509050808203828111612107579050905060065560e05160c0525b60206122055f395f5163a9059cbb6101005260206121c56101203960c051610140526020610100604461011c5f855af161207d573d5f5f3e3d5ffd5b3d61209457803b15612107576001610160526120be565b3d602081183d602010021880610100016101201161210757610100518060011c6121075761016052505b61016090505115612107577f5393ab6ef9bb40d91d1b04bbbeb707fbf3d1eb73f46744e2d179e4996026283f60c05161010052608051610120526040610100a160c0518152505b565b5f80fd0263001819a2038101e708281a1419dc09201a141984072a1a1419f8160402b518291a141a141a1419c000381a14145b187a114d18ac17821a140000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000000062afbde1181c71c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000075f610f70ed2000000000000000000000000000d6a1147666f6e4d7161caf436d9923d44d90111200000000000000000000000083f24023d15d835a213df24fd309c47dab5beb32000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e0000000000000000000000003e5a6c61488de85383fb0efd8c152d3e10c6bfe60000000000000000000000000000000000000000000000000000000000000001

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.