S Price: $0.717653 (-1.37%)

Contract

0xe9B460653B07D01fCdcD81D754c87b985D14fD52

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
104061662025-02-26 23:26:3019 hrs ago1740612390  Contract Creation0 S
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x8fA5B216...C1669AbEd
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:
SemiLog monetary policy

Compiler Version
vyper:0.3.10

Optimization Enabled:
N/A

Other Settings:
default evmVersion, None license

Contract Source Code (Vyper language format)

# @version 0.3.10
# pragma optimize codesize
# pragma evm-version shanghai
"""
@title SemiLog monetary policy
@notice Monetary policy to calculate borrow rates in lending markets depending on utilization.
        Unlike "core" policies, it does not depend on crvUSD price.
        Calculated as:
        log(rate) = utilization * (log(rate_max) - log(rate_min)) + log(rate_min)
        e.g.
        rate = rate_min * (rate_max / rate_min)**utilization
@author Curve.fi
@license Copyright (c) Curve.Fi, 2020-2024 - all rights reserved
"""
from vyper.interfaces import ERC20


interface Controller:
    def total_debt() -> uint256: view

interface Factory:
    def admin() -> address: view


event SetRates:
    min_rate: uint256
    max_rate: uint256


MAX_EXP: constant(uint256) = 1000 * 10**18
MIN_RATE: public(constant(uint256)) = 10**15 / (365 * 86400)  # 0.1%
MAX_RATE: public(constant(uint256)) = 10**19 / (365 * 86400)  # 1000%

BORROWED_TOKEN: public(immutable(ERC20))
FACTORY: public(immutable(Factory))

min_rate: public(uint256)
max_rate: public(uint256)
log_min_rate: public(int256)
log_max_rate: public(int256)


@external
def __init__(borrowed_token: ERC20, min_rate: uint256, max_rate: uint256):
    assert min_rate >= MIN_RATE and max_rate <= MAX_RATE and min_rate <= max_rate, "Wrong rates"

    BORROWED_TOKEN = borrowed_token
    self.min_rate = min_rate
    self.max_rate = max_rate
    self.log_min_rate = self.ln_int(min_rate)
    self.log_max_rate = self.ln_int(max_rate)

    FACTORY = Factory(msg.sender)


### MATH ###
@internal
@pure
def exp(power: int256) -> uint256:
    if power <= -41446531673892821376:
        return 0

    if power >= 135305999368893231589:
        # Return MAX_EXP when we are in overflow mode
        return MAX_EXP

    x: int256 = unsafe_div(unsafe_mul(power, 2**96), 10**18)

    k: int256 = unsafe_div(
        unsafe_add(
            unsafe_div(unsafe_mul(x, 2**96), 54916777467707473351141471128),
            2**95),
        2**96)
    x = unsafe_sub(x, unsafe_mul(k, 54916777467707473351141471128))

    y: int256 = unsafe_add(x, 1346386616545796478920950773328)
    y = unsafe_add(unsafe_div(unsafe_mul(y, x), 2**96), 57155421227552351082224309758442)
    p: int256 = unsafe_sub(unsafe_add(y, x), 94201549194550492254356042504812)
    p = unsafe_add(unsafe_div(unsafe_mul(p, y), 2**96), 28719021644029726153956944680412240)
    p = unsafe_add(unsafe_mul(p, x), (4385272521454847904659076985693276 * 2**96))

    q: int256 = x - 2855989394907223263936484059900
    q = unsafe_add(unsafe_div(unsafe_mul(q, x), 2**96), 50020603652535783019961831881945)
    q = unsafe_sub(unsafe_div(unsafe_mul(q, x), 2**96), 533845033583426703283633433725380)
    q = unsafe_add(unsafe_div(unsafe_mul(q, x), 2**96), 3604857256930695427073651918091429)
    q = unsafe_sub(unsafe_div(unsafe_mul(q, x), 2**96), 14423608567350463180887372962807573)
    q = unsafe_add(unsafe_div(unsafe_mul(q, x), 2**96), 26449188498355588339934803723976023)

    return shift(
        unsafe_mul(convert(unsafe_div(p, q), uint256), 3822833074963236453042738258902158003155416615667),
        unsafe_sub(k, 195))


@internal
@pure
def ln_int(_x: uint256) -> int256:
    """
    @notice Logarithm ln() function based on log2. Not very gas-efficient but brief
    """
    # adapted from: https://medium.com/coinmonks/9aef8515136e
    # and vyper log implementation
    # This can be much more optimal but that's not important here
    x: uint256 = _x
    if _x < 10**18:
        x = 10**36 / _x
    res: uint256 = 0
    for i in range(8):
        t: uint256 = 2**(7 - i)
        p: uint256 = 2**t
        if x >= p * 10**18:
            x /= p
            res += t * 10**18
    d: uint256 = 10**18
    for i in range(59):  # 18 decimals: math.log2(10**18) == 59.7
        if (x >= 2 * 10**18):
            res += d
            x /= 2
        x = x * x / 10**18
        d /= 2
    # Now res = log2(x)
    # ln(x) = log2(x) / log2(e)
    result: int256 = convert(res * 10**18 / 1442695040888963328, int256)
    if _x >= 10**18:
        return result
    else:
        return -result
### END MATH ###


@internal
@view
def calculate_rate(_for: address, d_reserves: int256, d_debt: int256) -> uint256:
    total_debt: int256 = convert(Controller(_for).total_debt(), int256)
    total_reserves: int256 = convert(BORROWED_TOKEN.balanceOf(_for), int256) + total_debt + d_reserves
    total_debt += d_debt
    assert total_debt >= 0, "Negative debt"
    assert total_reserves >= total_debt, "Reserves too small"
    if total_debt == 0:
        return self.min_rate
    else:
        log_min_rate: int256 = self.log_min_rate
        log_max_rate: int256 = self.log_max_rate
        return self.exp(total_debt * (log_max_rate - log_min_rate) / total_reserves + log_min_rate)


@view
@external
def rate(_for: address = msg.sender) -> uint256:
    return self.calculate_rate(_for, 0, 0)


@external
def rate_write(_for: address = msg.sender) -> uint256:
    return self.calculate_rate(_for, 0, 0)


@external
def set_rates(min_rate: uint256, max_rate: uint256):
    assert msg.sender == FACTORY.admin()

    assert max_rate >= min_rate
    assert min_rate >= MIN_RATE
    assert max_rate <= MAX_RATE

    if min_rate != self.min_rate:
        self.log_min_rate = self.ln_int(min_rate)
    if max_rate != self.max_rate:
        self.log_max_rate = self.ln_int(max_rate)
    self.min_rate = min_rate
    self.max_rate = max_rate

    log SetRates(min_rate, max_rate)


@view
@external
def future_rate(_for: address, d_reserves: int256, d_debt: int256) -> uint256:
    return self.calculate_rate(_for, d_reserves, d_debt)

Contract Security Audit

Contract ABI

[{"name":"SetRates","inputs":[{"name":"min_rate","type":"uint256","indexed":false},{"name":"max_rate","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"borrowed_token","type":"address"},{"name":"min_rate","type":"uint256"},{"name":"max_rate","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"rate","inputs":[{"name":"_for","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"rate_write","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"rate_write","inputs":[{"name":"_for","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"set_rates","inputs":[{"name":"min_rate","type":"uint256"},{"name":"max_rate","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"future_rate","inputs":[{"name":"_for","type":"address"},{"name":"d_reserves","type":"int256"},{"name":"d_debt","type":"int256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"MIN_RATE","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"MAX_RATE","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"BORROWED_TOKEN","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"FACTORY","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"min_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"max_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"log_min_rate","inputs":[],"outputs":[{"name":"","type":"int256"}]},{"stateMutability":"view","type":"function","name":"log_max_rate","inputs":[],"outputs":[{"name":"","type":"int256"}]}]

Deployed Bytecode

0x5f3560e01c6005600560018316026109b001601b395f51600760078260ff16848460181c0260181c06028260081c61ffff1601601939505f51818160181c14600336111661004c5761026e565b8060fe163610348260011602176109ac578060081c61ffff16565b6301e3da5f60405260206040f35b6449d482455d60405260206040f35b6020610a1c60403960206040f35b6020610a3c60403960206040f35b5f5460405260206040f35b60015460405260206040f35b60025460405260206040f35b60035460405260206040f35b33610200526100e9565b6004358060a01c6109ac57610200525b602061020051610100526040366101203761010561022061073c565b610220f35b3361020052610124565b6004358060a01c6109ac57610200525b602061020051610100526040366101203761014061022061073c565b610220f35b6020610a3c5f395f5163f851a440610100526020610100600461011c845afa610170573d5f5f3e3d5ffd5b60203d106109ac57610100518060a01c6109ac576101405261014090505133186109ac57600435602435106109ac576301e3da5f600435106109ac576449d482455d602435116109ac575f54600435146101dd576004356040526101d5610100610272565b610100516002555b60015460243514610201576024356040526101f9610100610272565b610100516003555b6004355f556024356001557f43abda41e7975fc65795be1b59318ab34e5bfc3072a1dff0904fbb0a13dd9b5c60406004610100376040610100a1005b6004358060a01c6109ac576102005260206102005161010052604060246101203761026961022061073c565b610220f35b5f5ffd5b604051606052670de0b6b3a763ffff604051116102aa5760405180156109ac57806ec097ce7bc90715b34b9f10000000000490506060525b5f6080525f6008905b8060a05260a05180600703600781116109ac57905060ff81116109ac578060020a905060c05260c05160ff81116109ac578060020a905060e05260e051670de0b6b3a7640000810281670de0b6b3a76400008204186109ac579050606051106103625760605160e05180156109ac578082049050905060605260805160c051670de0b6b3a7640000810281670de0b6b3a76400008204186109ac5790508082018281106109ac57905090506080525b6001018181186102b3575050670de0b6b3a764000060a0525f603b905b8060c052671bc16d674ec80000606051106103b85760805160a0518082018281106109ac57905090506080526060518060011c90506060525b6060516060518082028115838383041417156109ac5790509050670de0b6b3a76400008104905060605260a0518060011c905060a05260010181811861037f575050608051670de0b6b3a7640000810281670de0b6b3a76400008204186109ac5790506714057b7ef7678100810490508060ff1c6109ac5760c052670de0b6b3a7640000604051101561047d5760c0517f800000000000000000000000000000000000000000000000000000000000000081146109ac575f0381525061048456610484565b60c0518152505b565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a46680604051136104b8575f81525061073a565b680755bf798b4a1bf1e5604051126104dc57683635c9adc5dea0000081525061073a565b670de0b6b3a764000060405160601b056060526c010000000000000000000000006b8000000000000000000000006bb17217f7d1cf79abc9e3b39860605160601b0501056080526bb17217f7d1cf79abc9e3b39860805102606051036060526c10fe68e7fd37d0007b713f76506060510160a0526d02d16720577bd19bf614176fe9ea6c0100000000000000000000000060605160a05102050160a0526d04a4fd9f2a8b96949216d2255a6c60605160a051010360c0526e0587f503bb6ea29d25fcb7401964506c0100000000000000000000000060a05160c05102050160c05279d835ebba824c98fb31b83b2ca45c00000000000000000000000060605160c051020160c0526060516c240c330e9fb2d9cbaf0fd5aafc81038181136109ac57905060e0526d0277594991cfc85f6e2461837cd96c0100000000000000000000000060605160e05102050160e0526d1a521255e34f6a5061b25ef1c9c46c0100000000000000000000000060605160e05102050360e0526db1bbb201f443cf962f1a1d3db4a56c0100000000000000000000000060605160e05102050160e0526e02c72388d9f74f51a9331fed693f156c0100000000000000000000000060605160e05102050360e0526e05180bb14799ab47a8a8cb2a527d576c0100000000000000000000000060605160e05102050160e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e05160c051055f81126109ac570260c3608051037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81131561072c5781811b610732565b81815f031c5b905090508152505b565b610100516331dc3ca8610180526020610180600461019c845afa610762573d5f5f3e3d5ffd5b60203d106109ac576101809050518060ff1c6109ac57610160526020610a1c5f395f516370a082316101a052610100516101c05260206101a060246101bc845afa6107af573d5f5f3e3d5ffd5b60203d106109ac576101a09050518060ff1c6109ac57610160518082018281125f8312186109ac5790509050610120518082018281125f8312186109ac57905090506101805261016051610140518082018281125f8312186109ac5790509050610160525f61016051121561088357600d6101a0527f4e656761746976652064656274000000000000000000000000000000000000006101c0526101a0506101a051806101c001601f825f031636823750506308c379a061016052602061018052601f19601f6101a051011660440161017cfd5b610160516101805112156108f65760126101a0527f526573657276657320746f6f20736d616c6c00000000000000000000000000006101c0526101a0506101a051806101c001601f825f031636823750506308c379a061016052602061018052601f19601f6101a051011660440161017cfd5b6101605161090c575f548152506109aa566109aa565b6002546101a0526003546101c052610160516101c0516101a0518082038281135f8312186109ac579050905080820281191515600160ff1b84141517821584848405141716156109ac57905090506101805180156109ac57808205600160ff1b8314155f1983141517156109ac57905090506101a0518082018281125f8312186109ac57905090506040526109a26101e0610486565b6101e0518152505b565b5f80fd05de09dd09003e09ba055d78640100a005c24dbebd007505532da88b014545d819bfef0067059f3118d9023d658f24c6b600c305bdb09f2e0114252c4e722e00cf05e91f2f4c010a050ba9d8ca00d9252dd31000009205536e4ec400ab0582f75cee008405ecc92c1800b7050000000000000000000000007fff4c4a827c84e32c5e175052834111b2ccd2700000000000000000000000005dfad9014c12c89341d62ac8f0a9dfd690df0b74

Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

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