Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
20925172 | 112 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xfd8eF798...60ea33726 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
SemiLog monetary policy
Compiler Version
vyper:0.3.10
Contract Source Code (Vyper language format)
# @version 0.3.10 """ @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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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
0x5f3560e01c6002600b820660011b610a7701601e395f51565b63d819bfef81186100365734610a73576301e3da5f60405260206040f35b632dd31000811460033611161561005a5734610a73576020610aad60403960206040f35b63bdb09f2e811861033557602436103417610a73576004358060a01c610a7357610200525b602061020051610100526040366101203761009b610220610803565b610220f3610335565b63c24dbebd81186103355734610a73576449d482455d60405260206040f3610335565b6382f75cee81186100e55734610a73576020610a8d60403960206040f35b63ecc92c1881186103355734610a735760025460405260206040f3610335565b635d78640181186101205734610a73575f5460405260206040f35b63536e4ec481186103355734610a735760015460405260206040f3610335565b638f24c6b6811861015c5734610a735760035460405260206040f35b63e91f2f4c81186101765734610a7357336102005261007f565b63532da88b811861033557604436103417610a73576020610aad5f395f5163f851a440610100526020610100600461011c845afa6101b6573d5f5f3e3d5ffd5b60203d10610a7357610100518060a01c610a7357610140526101409050513318610a735760043560243510610a73576301e3da5f60043510610a73576449d482455d60243511610a73575f54600435146102235760043560405261021b610100610339565b610100516002555b600154602435146102475760243560405261023f610100610339565b610100516003555b6004355f556024356001557f43abda41e7975fc65795be1b59318ab34e5bfc3072a1dff0904fbb0a13dd9b5c60406004610100376040610100a100610335565b632c4e722e81186103355734610a735733610200526102ca56610335565b630ba9d8ca811861033557602436103417610a73576004358060a01c610a7357610200525b60206102005161010052604036610120376102e6610220610803565b610220f3610335565b639f3118d9811861033557606436103417610a73576004358060a01c610a735761020052602061020051610100526040602461012037610330610220610803565b610220f35b5f5ffd5b604051606052670de0b6b3a763ffff60405111610371576040518015610a7357806ec097ce7bc90715b34b9f10000000000490506060525b5f6080525f6008905b8060a05260a0518060070360078111610a7357905060ff8111610a73578060020a905060c05260c05160ff8111610a73578060020a905060e05260e051670de0b6b3a7640000810281670de0b6b3a7640000820418610a73579050606051106104295760605160e0518015610a73578082049050905060605260805160c051670de0b6b3a7640000810281670de0b6b3a7640000820418610a73579050808201828110610a7357905090506080525b60010181811861037a575050670de0b6b3a764000060a0525f603b905b8060c052671bc16d674ec800006060511061047f5760805160a051808201828110610a7357905090506080526060518060011c90506060525b606051606051808202811583838304141715610a735790509050670de0b6b3a76400008104905060605260a0518060011c905060a052600101818118610446575050608051670de0b6b3a7640000810281670de0b6b3a7640000820418610a735790506714057b7ef7678100810490508060ff1c610a735760c052670de0b6b3a764000060405110156105445760c0517f80000000000000000000000000000000000000000000000000000000000000008114610a73575f0381525061054b5661054b565b60c0518152505b565b7ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a466806040511361057f575f815250610801565b680755bf798b4a1bf1e5604051126105a357683635c9adc5dea00000815250610801565b670de0b6b3a764000060405160601b056060526c010000000000000000000000006b8000000000000000000000006bb17217f7d1cf79abc9e3b39860605160601b0501056080526bb17217f7d1cf79abc9e3b39860805102606051036060526c10fe68e7fd37d0007b713f76506060510160a0526d02d16720577bd19bf614176fe9ea6c0100000000000000000000000060605160a05102050160a0526d04a4fd9f2a8b96949216d2255a6c60605160a051010360c0526e0587f503bb6ea29d25fcb7401964506c0100000000000000000000000060a05160c05102050160c05279d835ebba824c98fb31b83b2ca45c00000000000000000000000060605160c051020160c0526060516c240c330e9fb2d9cbaf0fd5aafc8103818113610a7357905060e0526d0277594991cfc85f6e2461837cd96c0100000000000000000000000060605160e05102050160e0526d1a521255e34f6a5061b25ef1c9c46c0100000000000000000000000060605160e05102050360e0526db1bbb201f443cf962f1a1d3db4a56c0100000000000000000000000060605160e05102050160e0526e02c72388d9f74f51a9331fed693f156c0100000000000000000000000060605160e05102050360e0526e05180bb14799ab47a8a8cb2a527d576c0100000000000000000000000060605160e05102050160e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e05160c051055f8112610a73570260c3608051037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156107f35781811b6107f9565b81815f031c5b905090508152505b565b610100516331dc3ca8610180526020610180600461019c845afa610829573d5f5f3e3d5ffd5b60203d10610a73576101809050518060ff1c610a7357610160526020610a8d5f395f516370a082316101a052610100516101c05260206101a060246101bc845afa610876573d5f5f3e3d5ffd5b60203d10610a73576101a09050518060ff1c610a7357610160518082018281125f831218610a735790509050610120518082018281125f831218610a7357905090506101805261016051610140518082018281125f831218610a735790509050610160525f61016051121561094a57600d6101a0527f4e656761746976652064656274000000000000000000000000000000000000006101c0526101a0506101a051806101c001601f825f031636823750506308c379a061016052602061018052601f19601f6101a051011660440161017cfd5b610160516101805112156109bd5760126101a0527f526573657276657320746f6f20736d616c6c00000000000000000000000000006101c0526101a0506101a051806101c001601f825f031636823750506308c379a061016052602061018052601f19601f6101a051011660440161017cfd5b610160516109d3575f54815250610a7156610a71565b6002546101a0526003546101c052610160516101c0516101a0518082038281135f831218610a73579050905080820281191515600160ff1b8414151782158484840514171615610a735790509050610180518015610a7357808205600160ff1b8314155f198314151715610a7357905090506101a0518082018281125f831218610a735790509050604052610a696101e061054d565b6101e0518152505b565b5f80fd0140028700a403350335001802a502ef0335010500c7000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e000000000000000000000000ea6876dde9e3467564acbee1ed5bac88783205e0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.