ETH Price: $3,185.99 (+0.96%)
Gas: 4 Gwei

Contract

0x38E7627eb98a40e7528BcCe709A80083093Ba2F8
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x61148051199990462024-06-01 19:25:3542 days ago1717269935IN
 Contract Creation
0 ETH0.004797595.30751639

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xBcda2aCf...4f930A9F1
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
CryptoFromPoolsRate

Compiler Version
vyper:0.3.10

Optimization Enabled:
N/A

Other Settings:
MIT license

Contract Source Code (Vyper language format)

# @version 0.3.10
#pragma optimize gas
#pragma evm-version shanghai
"""
@title CryptoFromPoolsRate
@notice Price oracle for pools which contain cryptos and crvUSD. This is NOT suitable for minted crvUSD - only for lent out
        The oracle chains multiple pool oracles, and at the same time applies rate oracles if they are applicable
        This particular oracle us for UWU/crvUSD
@author Curve.Fi
@license MIT
"""

MAX_COINS: constant(uint256) = 8
MAX_POOLS: constant(uint256) = 8


interface Pool:
    def price_oracle(i: uint256 = 0) -> uint256: view  # Universal method!
    def coins(i: uint256) -> address: view
    def stored_rates() -> DynArray[uint256, MAX_COINS]: view


POOLS: public(immutable(DynArray[Pool, MAX_POOLS]))
BORROWED_IX: public(immutable(DynArray[uint256, MAX_POOLS]))
COLLATERAL_IX: public(immutable(DynArray[uint256, MAX_POOLS]))
NO_ARGUMENT: public(immutable(DynArray[bool, MAX_POOLS]))
POOL_COUNT: public(immutable(uint256))
USE_RATES: public(immutable(DynArray[bool, MAX_POOLS]))

RATE_MAX_SPEED: constant(uint256) = 10**16 / 60  # Max speed of Rate change

cached_timestamp: public(uint256)
cached_rate: public(uint256)


@external
def __init__(
        pools: DynArray[Pool, MAX_POOLS],
        borrowed_ixs: DynArray[uint256, MAX_POOLS],
        collateral_ixs: DynArray[uint256, MAX_POOLS]
    ):
    POOLS = pools
    pool_count: uint256 = 0
    no_arguments: DynArray[bool, MAX_POOLS] = empty(DynArray[bool, MAX_POOLS])
    use_rates: DynArray[bool, MAX_POOLS] = empty(DynArray[bool, MAX_POOLS])

    for i in range(MAX_POOLS):
        if i == len(pools):
            assert i != 0, "Wrong pool counts"
            pool_count = i
            break

        # Find N
        N: uint256 = 0
        for j in range(MAX_COINS + 1):
            success: bool = False
            res: Bytes[32] = empty(Bytes[32])
            success, res = raw_call(
                pools[i].address,
                _abi_encode(j, method_id=method_id("coins(uint256)")),
                max_outsize=32, is_static_call=True, revert_on_failure=False)
            if not success:
                assert j != 0, "No coins(0)"
                N = j
                break

        assert borrowed_ixs[i] != collateral_ixs[i]
        assert borrowed_ixs[i] < N
        assert collateral_ixs[i] < N

        # Init variables for raw call
        success: bool = False

        # Check and record if pool requires coin id in argument or no
        if N == 2:
            res: Bytes[32] = empty(Bytes[32])
            success, res = raw_call(
                pools[i].address,
                _abi_encode(empty(uint256), method_id=method_id("price_oracle(uint256)")),
                max_outsize=32, is_static_call=True, revert_on_failure=False)
            if not success:
                no_arguments.append(True)
            else:
                no_arguments.append(False)
        else:
            no_arguments.append(False)

        res: Bytes[1024] = empty(Bytes[1024])
        success, res = raw_call(pools[i].address, method_id("stored_rates()"), max_outsize=1024, is_static_call=True, revert_on_failure=False)
        stored_rates: DynArray[uint256, MAX_COINS] = empty(DynArray[uint256, MAX_COINS])
        if success and len(res) > 0:
            stored_rates = _abi_decode(res, DynArray[uint256, MAX_COINS])

        u: bool = False
        for r in stored_rates:
            if r != 10**18:
                u = True
        use_rates.append(u)

    NO_ARGUMENT = no_arguments
    BORROWED_IX = borrowed_ixs
    COLLATERAL_IX = collateral_ixs
    if pool_count == 0:
        pool_count = MAX_POOLS
    POOL_COUNT = pool_count
    USE_RATES = use_rates


@internal
@view
def _raw_stored_rate() -> (uint256, bool):
    rate: uint256 = 10**18
    use_rates: bool = False

    for i in range(MAX_POOLS):
        if i == POOL_COUNT:
            break
        if USE_RATES[i]:
            use_rates = True
            rates: DynArray[uint256, MAX_COINS] = POOLS[i].stored_rates()
            rate = rate * rates[COLLATERAL_IX[i]] / rates[BORROWED_IX[i]]

    return rate, use_rates


@internal
@view
def _stored_rate() -> (uint256, bool):
    use_rates: bool = False
    rate: uint256 = 0
    rate, use_rates = self._raw_stored_rate()
    if not use_rates:
        return rate, use_rates

    cached_rate: uint256 = self.cached_rate

    if cached_rate == 0 or cached_rate == rate:
        return rate, use_rates

    if rate > cached_rate:
        return min(rate, cached_rate * (10**18 + RATE_MAX_SPEED * (block.timestamp - self.cached_timestamp)) / 10**18), use_rates

    else:
        return max(rate, cached_rate * (10**18 - min(RATE_MAX_SPEED * (block.timestamp - self.cached_timestamp), 10**18)) / 10**18), use_rates


@external
@view
def stored_rate() -> uint256:
    return self._stored_rate()[0]


@internal
def _stored_rate_w() -> uint256:
    rate: uint256 = 0
    use_rates: bool = False
    rate, use_rates = self._stored_rate()
    if use_rates:
        self.cached_rate = rate
        self.cached_timestamp = block.timestamp
    return rate


@internal
@view
def _unscaled_price() -> uint256:
    _price: uint256 = 10**18
    for i in range(MAX_POOLS):
        if i >= POOL_COUNT:
            break
        p_borrowed: uint256 = 10**18
        p_collateral: uint256 = 10**18

        if NO_ARGUMENT[i]:
            p: uint256 = POOLS[i].price_oracle()
            if COLLATERAL_IX[i] > 0:
                p_collateral = p
            else:
                p_borrowed = p

        else:
            if BORROWED_IX[i] > 0:
                p_borrowed = POOLS[i].price_oracle(unsafe_sub(BORROWED_IX[i], 1))
            if COLLATERAL_IX[i] > 0:
                p_collateral = POOLS[i].price_oracle(unsafe_sub(COLLATERAL_IX[i], 1))
        _price = _price * p_collateral / p_borrowed
    return _price


@external
@view
def price() -> uint256:
    return self._unscaled_price() * self._stored_rate()[0] / 10**18


@external
def price_w() -> uint256:
    return self._unscaled_price() * self._stored_rate_w() / 10**18

Contract Security Audit

Contract ABI

[{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"pools","type":"address[]"},{"name":"borrowed_ixs","type":"uint256[]"},{"name":"collateral_ixs","type":"uint256[]"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"stored_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"price","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"price_w","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"POOLS","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"BORROWED_IX","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"COLLATERAL_IX","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"NO_ARGUMENT","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"POOL_COUNT","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"USE_RATES","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"cached_timestamp","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"cached_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]}]

Deployed Bytecode

0x5f3560e01c6002600a820660011b6108c001601e395f51565b63a8423c088118610055576024361034176108bc57602060043560206108d45f395f518110156108bc5760051b6020016108d40160403960206040f35b633304c622811861028c576024361034176108bc5760206004356020610d745f395f518110156108bc5760051b6104c0016108d40160403960206040f361028c565b6398f306a781186100d5576024361034176108bc57602060043560206109f45f395f518110156108bc5760051b610140016108d40160403960206040f35b63e7c222d1811861028c57346108bc575f5460405260206040f361028c565b6349ed544c8118610132576024361034176108bc5760206004356020610b145f395f518110156108bc5760051b610260016108d40160403960206040f35b6349abf236811861028c57346108bc576020610d5460403960206040f361028c565b63ce497f648118610192576024361034176108bc5760206004356020610c345f395f518110156108bc5760051b610380016108d40160403960206040f35b63fb4e5a0c811861028c57346108bc5760206101af6104c061042d565b6104c0f361028c565b63816239f181186101d457346108bc5760015460405260206040f35b63ceb7f759811861028c57346108bc576101ef610540610632565b610540516101fe6105606105f0565b610560518082028115838383041417156108bc5790509050670de0b6b3a764000081049050610580526020610580f361028c565b63a035b1fe811861028c57346108bc5761024d6104c0610632565b6104c05161025c6104e061042d565b6104e0518082028115838383041417156108bc5790509050670de0b6b3a764000081049050610520526020610520f35b5f5ffd5b670de0b6b3a76400006040525f6060525f6008905b806080526020610d545f395f51608051186102bf5761041b565b60206080516020610d745f395f518110156108bc5760051b6104c0016108d4015f395f5115610410576001606052602060805160206108d45f395f518110156108bc5760051b6020016108d4015f395f5163fd0684b16101c0526101406101c060046101dc845afa610333573d5f5f3e3d5ffd5b60403d106108bc576101c0516101c00160088151116108bc57805160208160051b0180610320828560045afa505050506103209050805160208160051b018060a0828560045afa5050505060405160206080516020610b145f395f518110156108bc5760051b610260016108d4015f395f5160a0518110156108bc5760051b60c001518082028115838383041417156108bc5790509050602060805160206109f45f395f518110156108bc5760051b610140016108d4015f395f5160a0518110156108bc5760051b60c0015180156108bc57808204905090506040525b6001018181186102a5575b50506040518152606051602082015250565b6040366104403761043f610480610290565b610480805161046052602081015161044052506104405161046f57610460518152610440516020820152506105ee565b6001546104805261048051610485576001610490565b610460516104805118155b156104aa57610460518152610440516020820152506105ee565b610480516104605111610564576104605161048051425f548082038281116108bc57905090506597951b766aaa8102816597951b766aaa8204186108bc579050670de0b6b3a7640000818118670de0b6b3a764000083100218905080670de0b6b3a764000003670de0b6b3a764000081116108bc5790508082028115838383041417156108bc5790509050670de0b6b3a764000081049050808281188284110218905090508152610440516020820152506105ee566105ee565b6104605161048051425f548082038281116108bc57905090506597951b766aaa8102816597951b766aaa8204186108bc57905080670de0b6b3a764000001670de0b6b3a764000081106108bc5790508082028115838383041417156108bc5790509050670de0b6b3a764000081049050808281188284100218905090508152610440516020820152505b565b6040366104c03761060261050061042d565b61050080516104c05260208101516104e052506104e05115610629576104c051600155425f555b6104c051815250565b670de0b6b3a76400006040525f6008905b806060526020610d545f395f516060511061065d576108b2565b670de0b6b3a7640000608052670de0b6b3a764000060a05260206060516020610c345f395f518110156108bc5760051b610380016108d4015f395f516107ed57602060605160206109f45f395f518110156108bc5760051b610140016108d4015f395f511561074357602060605160206108d45f395f518110156108bc5760051b6020016108d4015f395f51636872765360c0526001602060605160206109f45f395f518110156108bc5760051b610140016108d4015f395f510360e052602060c0602460dc845afa610732573d5f5f3e3d5ffd5b60203d106108bc5760c09050516080525b60206060516020610b145f395f518110156108bc5760051b610260016108d4015f395f511561087a57602060605160206108d45f395f518110156108bc5760051b6020016108d4015f395f51636872765360c052600160206060516020610b145f395f518110156108bc5760051b610260016108d4015f395f510360e052602060c0602460dc845afa6107d8573d5f5f3e3d5ffd5b60203d106108bc5760c090505160a05261087a565b602060605160206108d45f395f518110156108bc5760051b6020016108d4015f395f516386fc88d360e052602060e0600460fc845afa61082f573d5f5f3e3d5ffd5b60203d106108bc5760e090505160c05260206060516020610b145f395f518110156108bc5760051b610260016108d4015f395f51156108735760c05160a05261087a565b60c0516080525b60405160a0518082028115838383041417156108bc579050905060805180156108bc5780820490509050604052600101818118610643575b5050604051815250565b5f80fd00f4028c00180097023201b80154028c028c028c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000057064f49ad7123c92560882a45518374ad982e8500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Block Transaction Difficulty 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
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.