Address Contract Partially Verified
Address
0x966cBDeceFB60A289b0460F7638f4A75F432cA06
Balance
0 ETH
Nonce
1
Code Size
4013 bytes
Creator
0xbabe6188...9f67 at tx 0x2000981e...e99dca
Indexed Transactions
0 (1 on-chain, 0.6% indexed)
Contract Bytecode
4013 bytes
0x6003361161000c576104be565b60003560e01c34610d9b576333e3f712811861003c5760043610610d9b5760406100376102406107c8565b610240f35b63672485c181186100d65760043610610d9b57602061005c6103006107c8565b61030080516103a05260208101516103c052506020610e2d60003960005163a035b1fe610340526020610340600461035c845afa61009f573d600060003e3d6000fd5b60203d10610d9b576103409050516103e0526103a0516040526103c0516060526103e0516080526100d16103806109e6565b610380f35b63a035b1fe81186101705760043610610d9b5760206100f66103006107c8565b61030080516103a05260208101516103c052506020610e2d60003960005163a035b1fe610340526020610340600461035c845afa610139573d600060003e3d6000fd5b60203d10610d9b576103409050516103e0526103a0516040526103c0516060526103e05160805261016b6103806109e6565b610380f35b63ceb7f75981186102215760043610610d9b5761018e6103406107c8565b610340805161030052602081015161032052504260035410156101be574260035561030051600155610320516002555b602061030051604052610320516060526020610e2d60003960005163ceb7f759610340526020610340600461035c6000855af1610200573d600060003e3d6000fd5b60203d10610d9b5761034090505160805261021c6103806109e6565b610380f35b634f5002fa81186102985760243610610d9b576004358060011c610d9b576040526020610f2d60003960005163f851a440606052602060606004607c845afa61026f573d600060003e3d6000fd5b60203d10610d9b576060518060a01c610d9b5760a05260a09050513318610d9b57604051600055005b638419cf3981186102b65760043610610d9b57600260405260206040f35b63e26dca3781186102ec5760243610610d9b57602060043560018111610d9b5760051b610dad0160003960005160405260206040f35b63b345c2b881186103255760243610610d9b57602060043560018111610d9b5760051b604001610dad0160003960005160405260206040f35b63c959a716811861034c5760043610610d9b576020610e2d60003960005160405260206040f35b632c9bc96681186103855760243610610d9b57602060043560018111610d9b5760051b60a001610dad0160003960005160405260206040f35b6393a3977681186103ac5760043610610d9b576020610e8d60003960005160405260206040f35b63ca8c7dfb81186103e65760243610610d9b57602060043560018111610d9b5760051b61010001610dad0160003960005160405260206040f35b632dd31000811861040d5760043610610d9b576020610f2d60003960005160405260206040f35b63c19e2b7081186104345760043610610d9b576020610f8d60003960005160405260206040f35b63f4e1ae6281186104535760043610610d9b5760005460405260206040f35b6342e5a6c8811861047e5760243610610d9b5760043560018111610d9b576001015460405260206040f35b634d23bfa0811861049d5760043610610d9b5760035460405260206040f35b638d45972e81186104bc5760043610610d9b5761c35060405260206040f35b505b60006000fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1604051136104f75760008152506107c6565b680755bf798b4a1bf1e56040511261056657600c6060527f657870206f766572666c6f77000000000000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b670de0b6b3a764000060405160601b056060526c010000000000000000000000006b8000000000000000000000006bb17217f7d1cf79abc9e3b39860605160601b0501056080526bb17217f7d1cf79abc9e3b39860805102606051036060526c10fe68e7fd37d0007b713f76506060510160a0526d02d16720577bd19bf614176fe9ea6c0100000000000000000000000060605160a05102050160a0526d04a4fd9f2a8b96949216d2255a6c60605160a051010360c0526e0587f503bb6ea29d25fcb7401964506c0100000000000000000000000060a05160c05102050160c05279d835ebba824c98fb31b83b2ca45c00000000000000000000000060605160c051020160c0526060516c240c330e9fb2d9cbaf0fd5aafc8103818113610d9b57905060e0526d0277594991cfc85f6e2461837cd96c0100000000000000000000000060605160e05102050160e0526d1a521255e34f6a5061b25ef1c9c46c0100000000000000000000000060605160e05102050360e0526db1bbb201f443cf962f1a1d3db4a56c0100000000000000000000000060605160e05102050160e0526e02c72388d9f74f51a9331fed693f156c0100000000000000000000000060605160e05102050360e0526e05180bb14799ab47a8a8cb2a527d576c0100000000000000000000000060605160e05102050160e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e05160c0510560008112610d9b570260c3608051037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156107b75781811b6107be565b81816000031c5b905090508152505b565b600354610100526001546101205260025461014052426101005110156109d4574261010051808203828111610d9b5790509050670de0b6b3a7640000810281670de0b6b3a7640000820418610d9b57905061c350810490508060ff1c610d9b577f80000000000000000000000000000000000000000000000000000000000000008114610d9b576000036040526108606101806104c4565b610180516101605260006002905b806101805260206101805160018111610d9b5760051b610dad016000396000516318160ddd6101c05260206101c060046101dc845afa6108b3573d600060003e3d6000fd5b60203d10610d9b576101c090505160206101805160018111610d9b5760051b610dad01600039600051630c46b72a610200526020610200600461021c845afa610901573d600060003e3d6000fd5b60203d10610d9b57610200905051808202811583838304141715610d9b5790509050670de0b6b3a7640000810490506101a0526101a0516101605180670de0b6b3a764000003670de0b6b3a76400008111610d9b579050808202811583838304141715610d9b57905090506101805160018111610d9b5760051b610120015161016051808202811583838304141715610d9b5790509050808201828110610d9b5790509050670de0b6b3a7640000810490506101805160018111610d9b5760051b610120015260010181811861086e5750505b61012051815261014051602082015250565b60403660a03760006002905b8060e052602060e05160018111610d9b5760051b610dad01600039600051636872765361012052602060e05160018111610d9b5760051b604001610dad01600039600051610140526020610120602461013c845afa610a56573d600060003e3d6000fd5b60203d10610d9b5761012090505161010052602060e05160018111610d9b5760051b60a001610dad016000396000516386fc88d3610140526020610140600461015c845afa610aaa573d600060003e3d6000fd5b60203d10610d9b576101409050516101205260805161014052602060e05160018111610d9b5760051b61014001610dad0160003960005115610b0957610120518015610d9b57806ec097ce7bc90715b34b9f1000000000049050610120525b60e05160018111610d9b5760051b604001516101605260c05161016051808201828110610d9b579050905060c05260a0516101005161014051808202811583838304141715610d9b5790509050610120518015610d9b578082049050905061016051808202811583838304141715610d9b5790509050808201828110610d9b579050905060a0526001018181186109f257505060a05160c0518015610d9b578082049050905060e05260005415610d93576020610f4d60003960005163feaf968c6101a05260a06101a060046101bc845afa610bea573d600060003e3d6000fd5b60a03d10610d9b576101a0518060501c610d9b57610260526101c051610280526101e0516102a052610200516102c052610220518060501c610d9b576102e0526102609050805161010052602081015161012052604081015161014052606081015161016052608081015161018052506201518042610160514280828118828410021890509050808203828111610d9b579050905011610d93576101205160008112610d9b57670de0b6b3a7640000810281670de0b6b3a7640000820418610d9b5790506020610f6d6000396000518015610d9b57808204905090506101a0526101a0516020610f8d60003960005180670de0b6b3a764000003670de0b6b3a76400008111610d9b579050808202811583838304141715610d9b5790509050670de0b6b3a7640000810490506101c0526101a0516020610f8d60003960005180670de0b6b3a764000001670de0b6b3a76400008110610d9b579050808202811583838304141715610d9b5790509050670de0b6b3a7640000810490506101e05260e0516101c051808281188284110218905090506101e0518082811882841002189050905060e0525b60e051815250565b600080fda165767970657283000307000b0000000000000000000000007f86bf177dd4f3494b841a37e810a34dd56c829b000000000000000000000000f5f5b97624542d72a9e06f04804bf81baa15e2b40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000018672b1b0c623a30089a280ed9256379fb0e4e620000000000000000000000004dece678ceceb27446b35c672dc7d61f30bad69e000000000000000000000000390f3595bca2df7d23783dfd126427cceb997bf4000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9332fdcb1c491dcc683bae86fe3cb70360738bc0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000354a6ba7a18000
Verified Source Code Partial Match
Compiler: v0.3.7+commit.6020b8bb
EVM: paris
CryptoWithStablePriceETH.vy 216 lines
# @version 0.3.7
"""
@title CryptoWithStablePriceETH
@notice Price oracle for tricrypto for crvUSD. Optional Chainlink included
With old tricrypto2 it is UNSAFE to use. Should be tricrypto-ng only
@author Curve.Fi
@license MIT
"""
# Tricrypto-ng
interface Tricrypto:
def price_oracle(k: uint256) -> uint256: view
def coins(i: uint256) -> address: view
def totalSupply() -> uint256: view
def virtual_price() -> uint256: view
interface StableAggregator:
def price() -> uint256: view
def price_w() -> uint256: nonpayable
def stablecoin() -> address: view
interface Stableswap:
def price_oracle() -> uint256: view
def coins(i: uint256) -> address: view
interface ControllerFactory:
def admin() -> address: view
struct ChainlinkAnswer:
round_id: uint80
answer: int256
started_at: uint256
updated_at: uint256
answered_in_round: uint80
interface ChainlinkAggregator:
def latestRoundData() -> ChainlinkAnswer: view
def decimals() -> uint8: view
N_POOLS: public(constant(uint256)) = 2
TRICRYPTO: public(immutable(Tricrypto[N_POOLS]))
TRICRYPTO_IX: public(immutable(uint256[N_POOLS]))
STABLESWAP_AGGREGATOR: public(immutable(StableAggregator))
STABLESWAP: public(immutable(Stableswap[N_POOLS]))
STABLECOIN: public(immutable(address))
REDEEMABLE: public(immutable(address[N_POOLS]))
IS_INVERSE: immutable(bool[N_POOLS])
FACTORY: public(immutable(ControllerFactory))
CHAINLINK_AGGREGATOR_ETH: immutable(ChainlinkAggregator)
CHAINLINK_PRICE_PRECISION_ETH: immutable(uint256)
CHAINLINK_STALE_THRESHOLD: constant(uint256) = 86400
BOUND_SIZE: public(immutable(uint256))
use_chainlink: public(bool)
last_tvl: public(uint256[N_POOLS])
last_timestamp: public(uint256)
TVL_MA_TIME: public(constant(uint256)) = 50000 # s
@external
def __init__(
tricrypto: Tricrypto[N_POOLS],
ix: uint256[N_POOLS], # 1 = ETH
stableswap: Stableswap[N_POOLS],
stable_aggregator: StableAggregator,
factory: ControllerFactory,
chainlink_aggregator_btc: ChainlinkAggregator,
bound_size: uint256 # 1.5% sounds ok before we turn it off
):
TRICRYPTO = tricrypto
TRICRYPTO_IX = ix
STABLESWAP_AGGREGATOR = stable_aggregator
STABLESWAP = stableswap
FACTORY = factory
_stablecoin: address = stable_aggregator.stablecoin()
STABLECOIN = _stablecoin
_redeemable: address[N_POOLS] = empty(address[N_POOLS])
_is_inverse: bool[N_POOLS] = empty(bool[N_POOLS])
for i in range(N_POOLS):
coins: address[2] = [stableswap[i].coins(0), stableswap[i].coins(1)]
if coins[0] == _stablecoin:
_redeemable[i] = coins[1]
_is_inverse[i] = True
else:
_redeemable[i] = coins[0]
_is_inverse[i] = False
assert coins[1] == _stablecoin
assert tricrypto[i].coins(0) == _redeemable[i]
self.last_tvl[i] = tricrypto[i].totalSupply() * tricrypto[i].virtual_price() / 10**18
IS_INVERSE = _is_inverse
REDEEMABLE = _redeemable
self.use_chainlink = True
CHAINLINK_AGGREGATOR_ETH = chainlink_aggregator_btc
CHAINLINK_PRICE_PRECISION_ETH = 10**convert(chainlink_aggregator_btc.decimals(), uint256)
BOUND_SIZE = bound_size
@internal
@view
def exp(power: int256) -> uint256:
if power <= -42139678854452767551:
return 0
if power >= 135305999368893231589:
raise "exp overflow"
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
@view
def _ema_tvl() -> uint256[N_POOLS]:
last_timestamp: uint256 = self.last_timestamp
last_tvl: uint256[N_POOLS] = self.last_tvl
if last_timestamp < block.timestamp:
alpha: uint256 = self.exp(- convert((block.timestamp - last_timestamp) * 10**18 / TVL_MA_TIME, int256))
# alpha = 1.0 when dt = 0
# alpha = 0.0 when dt = inf
for i in range(N_POOLS):
tvl: uint256 = TRICRYPTO[i].totalSupply() * TRICRYPTO[i].virtual_price() / 10**18
last_tvl[i] = (tvl * (10**18 - alpha) + last_tvl[i] * alpha) / 10**18
return last_tvl
@external
@view
def ema_tvl() -> uint256[N_POOLS]:
return self._ema_tvl()
@internal
@view
def _raw_price(tvls: uint256[N_POOLS], agg_price: uint256) -> uint256:
weighted_price: uint256 = 0
weights: uint256 = 0
for i in range(N_POOLS):
p_crypto_r: uint256 = TRICRYPTO[i].price_oracle(TRICRYPTO_IX[i]) # d_usdt/d_eth
p_stable_r: uint256 = STABLESWAP[i].price_oracle() # d_usdt/d_st
p_stable_agg: uint256 = agg_price # d_usd/d_st
if IS_INVERSE[i]:
p_stable_r = 10**36 / p_stable_r
weight: uint256 = tvls[i]
# Prices are already EMA but weights - not so much
weights += weight
weighted_price += p_crypto_r * p_stable_agg / p_stable_r * weight # d_usd/d_eth
crv_p: uint256 = weighted_price / weights
# Limit BTC price
if self.use_chainlink:
chainlink_lrd: ChainlinkAnswer = CHAINLINK_AGGREGATOR_ETH.latestRoundData()
if block.timestamp - min(chainlink_lrd.updated_at, block.timestamp) <= CHAINLINK_STALE_THRESHOLD:
chainlink_p: uint256 = convert(chainlink_lrd.answer, uint256) * 10**18 / CHAINLINK_PRICE_PRECISION_ETH
lower: uint256 = chainlink_p * (10**18 - BOUND_SIZE) / 10**18
upper: uint256 = chainlink_p * (10**18 + BOUND_SIZE) / 10**18
crv_p = min(max(crv_p, lower), upper)
return crv_p
@external
@view
def raw_price() -> uint256:
return self._raw_price(self._ema_tvl(), STABLESWAP_AGGREGATOR.price())
@external
@view
def price() -> uint256:
return self._raw_price(self._ema_tvl(), STABLESWAP_AGGREGATOR.price())
@external
def price_w() -> uint256:
tvls: uint256[N_POOLS] = self._ema_tvl()
if self.last_timestamp < block.timestamp:
self.last_timestamp = block.timestamp
self.last_tvl = tvls
return self._raw_price(tvls, STABLESWAP_AGGREGATOR.price_w())
@external
def set_use_chainlink(do_it: bool):
assert msg.sender == FACTORY.admin()
self.use_chainlink = do_it
Read Contract
BOUND_SIZE 0xc19e2b70 → uint256
FACTORY 0x2dd31000 → address
N_POOLS 0x8419cf39 → uint256
REDEEMABLE 0xca8c7dfb → address
STABLECOIN 0x93a39776 → address
STABLESWAP 0x2c9bc966 → address
STABLESWAP_AGGREGATOR 0xc959a716 → address
TRICRYPTO 0xe26dca37 → address
TRICRYPTO_IX 0xb345c2b8 → uint256
TVL_MA_TIME 0x8d45972e → uint256
ema_tvl 0x33e3f712 → uint256[2]
last_timestamp 0x4d23bfa0 → uint256
last_tvl 0x42e5a6c8 → uint256
price 0xa035b1fe → uint256
raw_price 0x672485c1 → uint256
use_chainlink 0xf4e1ae62 → bool
Write Contract 2 functions
These functions modify contract state and require a wallet transaction to execute.
price_w 0xceb7f759
No parameters
returns: uint256
set_use_chainlink 0x4f5002fa
bool do_it
Recent Transactions
This address has 1 on-chain transactions, but only 0.6% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →