ETH Price: $2,936.72 (+4.14%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set_admin172580282023-05-14 12:13:23544 days ago1684066403IN
0xe5Afcf33...53762Dfe7
0 ETH0.0010509538.0409466
Add_price_pair172580252023-05-14 12:12:47544 days ago1684066367IN
0xe5Afcf33...53762Dfe7
0 ETH0.0027727741.43353436
Add_price_pair172580222023-05-14 12:12:11544 days ago1684066331IN
0xe5Afcf33...53762Dfe7
0 ETH0.0023271134.77402938
Add_price_pair172580192023-05-14 12:11:35544 days ago1684066295IN
0xe5Afcf33...53762Dfe7
0 ETH0.0025819738.58240425
Add_price_pair172580162023-05-14 12:10:59544 days ago1684066259IN
0xe5Afcf33...53762Dfe7
0 ETH0.0033077839.36852613
0x6020610b172580132023-05-14 12:10:11544 days ago1684066211IN
 Create: AggregatorStablePrice - aggregator of stablecoin prices for crvUSD
0 ETH0.0266953937.44782683

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AggregatorStablePrice - aggregator of stablecoin prices for crvUSD

Compiler Version
vyper:0.3.7

Optimization Enabled:
N/A

Other Settings:
None license

Contract Source Code (Vyper language format)

# @version 0.3.7
"""
@title AggregatorStablePrice - aggregator of stablecoin prices for crvUSD
@author Curve.Fi
@license Copyright (c) Curve.Fi, 2020-2023 - all rights reserved
"""
# Returns price of stablecoin in "dollars" based on multiple redeemable stablecoins
# Recommended to use 3+ price sources

interface Stableswap:
    def price_oracle() -> uint256: view
    def coins(i: uint256) -> address: view
    def get_virtual_price() -> uint256: view
    def totalSupply() -> uint256: view


struct PricePair:
    pool: Stableswap
    is_inverse: bool


event AddPricePair:
    n: uint256
    pool: Stableswap
    is_inverse: bool

event RemovePricePair:
    n: uint256

event MovePricePair:
    n_from: uint256
    n_to: uint256

event SetAdmin:
    admin: address


MAX_PAIRS: constant(uint256) = 20
MIN_LIQUIDITY: constant(uint256) = 100_000 * 10**18  # Only take into account pools with enough liquidity

STABLECOIN: immutable(address)
SIGMA: immutable(uint256)
price_pairs: public(PricePair[MAX_PAIRS])
n_price_pairs: uint256

admin: public(address)


@external
def __init__(stablecoin: address, sigma: uint256, admin: address):
    STABLECOIN = stablecoin
    SIGMA = sigma  # The change is so rare that we can change the whole thing altogether
    self.admin = admin


@external
def set_admin(_admin: address):
    # We are not doing commit / apply because the owner will be a voting DAO anyway
    # which has vote delays
    assert msg.sender == self.admin
    self.admin = _admin
    log SetAdmin(_admin)


@external
@view
def sigma() -> uint256:
    return SIGMA


@external
@view
def stablecoin() -> address:
    return STABLECOIN


@external
def add_price_pair(_pool: Stableswap):
    assert msg.sender == self.admin
    price_pair: PricePair = empty(PricePair)
    price_pair.pool = _pool
    coins: address[2] = [_pool.coins(0), _pool.coins(1)]
    if coins[0] == STABLECOIN:
        price_pair.is_inverse = True
    else:
        assert coins[1] == STABLECOIN
    n: uint256 = self.n_price_pairs
    self.price_pairs[n] = price_pair  # Should revert if too many pairs
    self.n_price_pairs = n + 1
    log AddPricePair(n, _pool, price_pair.is_inverse)


@external
def remove_price_pair(n: uint256):
    assert msg.sender == self.admin
    n_max: uint256 = self.n_price_pairs - 1
    assert n <= n_max

    if n < n_max:
        self.price_pairs[n] = self.price_pairs[n_max]
        log MovePricePair(n_max, n)
    self.n_price_pairs = n_max
    log RemovePricePair(n)


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


@external
@view
def price() -> uint256:
    n: uint256 = self.n_price_pairs
    prices: uint256[MAX_PAIRS] = empty(uint256[MAX_PAIRS])
    D: uint256[MAX_PAIRS] = empty(uint256[MAX_PAIRS])
    Dsum: uint256 = 0
    DPsum: uint256 = 0
    for i in range(MAX_PAIRS):
        if i == n:
            break
        price_pair: PricePair = self.price_pairs[i]
        pool_supply: uint256 = price_pair.pool.totalSupply()
        if pool_supply >= MIN_LIQUIDITY:
            p: uint256 = price_pair.pool.price_oracle()
            if price_pair.is_inverse:
                p = 10**36 / p
            prices[i] = p
            _D: uint256 = price_pair.pool.get_virtual_price() * pool_supply / 10**18
            D[i] = _D
            Dsum += _D
            DPsum += _D * p
    if Dsum == 0:
        return 10**18  # Placeholder for no active pools
    p_avg: uint256 = DPsum / Dsum
    e: uint256[MAX_PAIRS] = empty(uint256[MAX_PAIRS])
    e_min: uint256 = max_value(uint256)
    for i in range(MAX_PAIRS):
        if i == n:
            break
        p: uint256 = prices[i]
        e[i] = (max(p, p_avg) - min(p, p_avg))**2 / (SIGMA**2 / 10**18)
        e_min = min(e[i], e_min)
    wp_sum: uint256 = 0
    w_sum: uint256 = 0
    for i in range(MAX_PAIRS):
        if i == n:
            break
        w: uint256 = D[i] * self.exp(-convert(e[i] - e_min, int256)) / 10**18
        w_sum += w
        wp_sum += w * prices[i]
    return wp_sum / w_sum

Contract Security Audit

Contract ABI

[{"name":"AddPricePair","inputs":[{"name":"n","type":"uint256","indexed":false},{"name":"pool","type":"address","indexed":false},{"name":"is_inverse","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemovePricePair","inputs":[{"name":"n","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"MovePricePair","inputs":[{"name":"n_from","type":"uint256","indexed":false},{"name":"n_to","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetAdmin","inputs":[{"name":"admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"stablecoin","type":"address"},{"name":"sigma","type":"uint256"},{"name":"admin","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_admin","inputs":[{"name":"_admin","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"sigma","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"stablecoin","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"nonpayable","type":"function","name":"add_price_pair","inputs":[{"name":"_pool","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"remove_price_pair","inputs":[{"name":"n","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"price","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"price_pairs","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"pool","type":"address"},{"name":"is_inverse","type":"bool"}]}]},{"stateMutability":"view","type":"function","name":"admin","inputs":[],"outputs":[{"name":"","type":"address"}]}]

6020610bb06000396000518060a01c610bab576040526020610bf06000396000518060a01c610bab5760605234610bab57604051610b4c526020610bd0600039600051610b6c52606051602955610b4c61005e61000039610b8c610000f36003361161000c57610830565b60003560e01c34610b3a5763e9333fab81186100755760243610610b3a576004358060a01c610b3a576040526029543318610b3a576040516029557f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a160405160605260206060a1005b63afdf31cd811861009c5760043610610b3a576020610b6c60003960005160405260206040f35b63e9cbd82281186100c35760043610610b3a576020610b4c60003960005160405260206040f35b63a51ec1dd81186102375760243610610b3a576004358060a01c610b3a576040526029543318610b3a5760403660603760405160605260405163c661065760e052600061010052602060e0602460fc845afa610124573d600060003e3d6000fd5b60203d10610b3a5760e0518060a01c610b3a576101205261012090505160a05260405163c6610657610140526001610160526020610140602461015c845afa610172573d600060003e3d6000fd5b60203d10610b3a57610140518060a01c610b3a576101805261018090505160c0526020610b4c60003960005160a051186101b05760016080526101c4565b6020610b4c60003960005160c05118610b3a575b60285460e05260e05160138111610b3a5760011b606051815560805160018201555060e05160018101818110610b3a5790506028557ffa41d19543baad0c0257c3430e1b3cecfa57f753cdc21330b9ec0862cde1b25860e0516101005260405161012052608051610140526060610100a1005b63b3162fdb81186103105760243610610b3a576029543318610b3a5760285460018103818111610b3a57905060405260405160043511610b3a5760405160043510156102dc5760043560138111610b3a5760011b60405160138111610b3a5760011b805482556001810154600183015550507f3be85492dc07bf3888ee5d022674f0eced07fa5845d47b118257a8a0616d97ec60405160605260043560805260406060a15b6040516028557f017592f2f16e82cccce60102865c737270289c308f34ff88e754d5e99ea0bae160043560605260206060a1005b63a035b1fe81186107da5760043610610b3a5760285461010052610540366101203760006014905b806106605261010051610660511861034f5761050c565b6106605160138111610b3a5760011b80546106805260018101546106a05250610680516318160ddd6106e05260206106e060046106fc845afa610397573d600060003e3d6000fd5b60203d10610b3a576106e09050516106c05269152d02c7e14af68000006106c0511061050157610680516386fc88d3610700526020610700600461071c845afa6103e6573d600060003e3d6000fd5b60203d10610b3a576107009050516106e0526106a05115610424576106e0518015610b3a57806ec097ce7bc90715b34b9f10000000000490506106e0525b6106e0516106605160138111610b3a5760051b61012001526106805163bb7b8b80610720526020610720600461073c845afa610465573d600060003e3d6000fd5b60203d10610b3a576107209050516106c051808202811583838304141715610b3a5790509050670de0b6b3a76400008104905061070052610700516106605160138111610b3a5760051b6103a001526106205161070051808201828110610b3a57905090506106205261064051610700516106e051808202811583838304141715610b3a5790509050808201828110610b3a5790509050610640525b600101818118610338575b50506106205161052d57670de0b6b3a76400006106605260206106606107d8565b61064051610620518015610b3a57808204905090506106605261028036610680377fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6109005260006014905b806109205261010051610920511861059057610687565b6109205160138111610b3a5760051b610120015161094052610940516106605180828118828411021890509050610940516106605180828118828410021890509050808203828111610b3a57905090506fffffffffffffffffffffffffffffffff8111610b3a576002810a90506020610b6c6000396000516fffffffffffffffffffffffffffffffff8111610b3a576002810a9050670de0b6b3a7640000810490508015610b3a57808204905090506109205160138111610b3a5760051b61068001526109205160138111610b3a5760051b6106800151610900518082811882841002189050905061090052600101818118610579575b50506040366109203760006014905b80610960526101005161096051186106ad576107b7565b6109605160138111610b3a5760051b6103a001516109605160138111610b3a5760051b610680015161090051808203828111610b3a57905090508060ff1c610b3a577f80000000000000000000000000000000000000000000000000000000000000008114610b3a576000036040526107276109a0610836565b6109a051808202811583838304141715610b3a5790509050670de0b6b3a764000081049050610980526109405161098051808201828110610b3a57905090506109405261092051610980516109605160138111610b3a5760051b6101200151808202811583838304141715610b3a5790509050808201828110610b3a579050905061092052600101818118610696575b505061092051610940518015610b3a57808204905090506109605260206109605bf35b63ba5feb37811861080f5760243610610b3a5760043560138111610b3a5760011b805460405260018101546060525060406040f35b63f851a440811861082e5760043610610b3a5760295460405260206040f35b505b60006000fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c160405113610869576000815250610b38565b680755bf798b4a1bf1e5604051126108d857600c6060527f657870206f766572666c6f77000000000000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b670de0b6b3a764000060405160601b056060526c010000000000000000000000006b8000000000000000000000006bb17217f7d1cf79abc9e3b39860605160601b0501056080526bb17217f7d1cf79abc9e3b39860805102606051036060526c10fe68e7fd37d0007b713f76506060510160a0526d02d16720577bd19bf614176fe9ea6c0100000000000000000000000060605160a05102050160a0526d04a4fd9f2a8b96949216d2255a6c60605160a051010360c0526e0587f503bb6ea29d25fcb7401964506c0100000000000000000000000060a05160c05102050160c05279d835ebba824c98fb31b83b2ca45c00000000000000000000000060605160c051020160c0526060516c240c330e9fb2d9cbaf0fd5aafc8103818113610b3a57905060e0526d0277594991cfc85f6e2461837cd96c0100000000000000000000000060605160e05102050160e0526d1a521255e34f6a5061b25ef1c9c46c0100000000000000000000000060605160e05102050360e0526db1bbb201f443cf962f1a1d3db4a56c0100000000000000000000000060605160e05102050160e0526e02c72388d9f74f51a9331fed693f156c0100000000000000000000000060605160e05102050360e0526e05180bb14799ab47a8a8cb2a527d576c0100000000000000000000000060605160e05102050160e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e05160c0510560008112610b3a570260c3608051037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811315610b295781811b610b30565b81816000031c5b905090508152505b565b600080fda165767970657283000307000b005b600080fd000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000babe61887f1de2713c6f97e567623453d3c79f67

Deployed Bytecode

0x6003361161000c57610830565b60003560e01c34610b3a5763e9333fab81186100755760243610610b3a576004358060a01c610b3a576040526029543318610b3a576040516029557f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a160405160605260206060a1005b63afdf31cd811861009c5760043610610b3a576020610b6c60003960005160405260206040f35b63e9cbd82281186100c35760043610610b3a576020610b4c60003960005160405260206040f35b63a51ec1dd81186102375760243610610b3a576004358060a01c610b3a576040526029543318610b3a5760403660603760405160605260405163c661065760e052600061010052602060e0602460fc845afa610124573d600060003e3d6000fd5b60203d10610b3a5760e0518060a01c610b3a576101205261012090505160a05260405163c6610657610140526001610160526020610140602461015c845afa610172573d600060003e3d6000fd5b60203d10610b3a57610140518060a01c610b3a576101805261018090505160c0526020610b4c60003960005160a051186101b05760016080526101c4565b6020610b4c60003960005160c05118610b3a575b60285460e05260e05160138111610b3a5760011b606051815560805160018201555060e05160018101818110610b3a5790506028557ffa41d19543baad0c0257c3430e1b3cecfa57f753cdc21330b9ec0862cde1b25860e0516101005260405161012052608051610140526060610100a1005b63b3162fdb81186103105760243610610b3a576029543318610b3a5760285460018103818111610b3a57905060405260405160043511610b3a5760405160043510156102dc5760043560138111610b3a5760011b60405160138111610b3a5760011b805482556001810154600183015550507f3be85492dc07bf3888ee5d022674f0eced07fa5845d47b118257a8a0616d97ec60405160605260043560805260406060a15b6040516028557f017592f2f16e82cccce60102865c737270289c308f34ff88e754d5e99ea0bae160043560605260206060a1005b63a035b1fe81186107da5760043610610b3a5760285461010052610540366101203760006014905b806106605261010051610660511861034f5761050c565b6106605160138111610b3a5760011b80546106805260018101546106a05250610680516318160ddd6106e05260206106e060046106fc845afa610397573d600060003e3d6000fd5b60203d10610b3a576106e09050516106c05269152d02c7e14af68000006106c0511061050157610680516386fc88d3610700526020610700600461071c845afa6103e6573d600060003e3d6000fd5b60203d10610b3a576107009050516106e0526106a05115610424576106e0518015610b3a57806ec097ce7bc90715b34b9f10000000000490506106e0525b6106e0516106605160138111610b3a5760051b61012001526106805163bb7b8b80610720526020610720600461073c845afa610465573d600060003e3d6000fd5b60203d10610b3a576107209050516106c051808202811583838304141715610b3a5790509050670de0b6b3a76400008104905061070052610700516106605160138111610b3a5760051b6103a001526106205161070051808201828110610b3a57905090506106205261064051610700516106e051808202811583838304141715610b3a5790509050808201828110610b3a5790509050610640525b600101818118610338575b50506106205161052d57670de0b6b3a76400006106605260206106606107d8565b61064051610620518015610b3a57808204905090506106605261028036610680377fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6109005260006014905b806109205261010051610920511861059057610687565b6109205160138111610b3a5760051b610120015161094052610940516106605180828118828411021890509050610940516106605180828118828410021890509050808203828111610b3a57905090506fffffffffffffffffffffffffffffffff8111610b3a576002810a90506020610b6c6000396000516fffffffffffffffffffffffffffffffff8111610b3a576002810a9050670de0b6b3a7640000810490508015610b3a57808204905090506109205160138111610b3a5760051b61068001526109205160138111610b3a5760051b6106800151610900518082811882841002189050905061090052600101818118610579575b50506040366109203760006014905b80610960526101005161096051186106ad576107b7565b6109605160138111610b3a5760051b6103a001516109605160138111610b3a5760051b610680015161090051808203828111610b3a57905090508060ff1c610b3a577f80000000000000000000000000000000000000000000000000000000000000008114610b3a576000036040526107276109a0610836565b6109a051808202811583838304141715610b3a5790509050670de0b6b3a764000081049050610980526109405161098051808201828110610b3a57905090506109405261092051610980516109605160138111610b3a5760051b6101200151808202811583838304141715610b3a5790509050808201828110610b3a579050905061092052600101818118610696575b505061092051610940518015610b3a57808204905090506109605260206109605bf35b63ba5feb37811861080f5760243610610b3a5760043560138111610b3a5760011b805460405260018101546060525060406040f35b63f851a440811861082e5760043610610b3a5760295460405260206040f35b505b60006000fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c160405113610869576000815250610b38565b680755bf798b4a1bf1e5604051126108d857600c6060527f657870206f766572666c6f77000000000000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b670de0b6b3a764000060405160601b056060526c010000000000000000000000006b8000000000000000000000006bb17217f7d1cf79abc9e3b39860605160601b0501056080526bb17217f7d1cf79abc9e3b39860805102606051036060526c10fe68e7fd37d0007b713f76506060510160a0526d02d16720577bd19bf614176fe9ea6c0100000000000000000000000060605160a05102050160a0526d04a4fd9f2a8b96949216d2255a6c60605160a051010360c0526e0587f503bb6ea29d25fcb7401964506c0100000000000000000000000060a05160c05102050160c05279d835ebba824c98fb31b83b2ca45c00000000000000000000000060605160c051020160c0526060516c240c330e9fb2d9cbaf0fd5aafc8103818113610b3a57905060e0526d0277594991cfc85f6e2461837cd96c0100000000000000000000000060605160e05102050160e0526d1a521255e34f6a5061b25ef1c9c46c0100000000000000000000000060605160e05102050360e0526db1bbb201f443cf962f1a1d3db4a56c0100000000000000000000000060605160e05102050160e0526e02c72388d9f74f51a9331fed693f156c0100000000000000000000000060605160e05102050360e0526e05180bb14799ab47a8a8cb2a527d576c0100000000000000000000000060605160e05102050160e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e05160c0510560008112610b3a570260c3608051037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811315610b295781811b610b30565b81816000031c5b905090508152505b565b600080fda165767970657283000307000b000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e00000000000000000000000000000000000000000000000000038d7ea4c68000

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000babe61887f1de2713c6f97e567623453d3c79f67

-----Decoded View---------------
Arg [0] : stablecoin (address): 0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E
Arg [1] : sigma (uint256): 1000000000000000
Arg [2] : admin (address): 0xbabe61887f1de2713c6f97e567623453d3C79f67

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e
Arg [1] : 00000000000000000000000000000000000000000000000000038d7ea4c68000
Arg [2] : 000000000000000000000000babe61887f1de2713c6f97e567623453d3c79f67


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.