Forkchoice Ethereum Mainnet

Address Contract Verified

Address 0x4F67e4d9BD67eFa28236013288737D39AeF48e79
Balance 0 ETH
Nonce 1
Code Size 1581 bytes
Indexed Transactions 0 (1 on-chain, 1.4% indexed)
External Etherscan · Sourcify

Contract Bytecode

1581 bytes
Copy Bytecode
0x608060408181526004918236101561001657600080fd5b600090813560e01c90816317f098ca146105245750806322c2b36c146104e9578063313ce567146104ab5780634aa07e641461046757806354fd4d501461044b5780637284e416146103a0578063ed1a68d1146103585763feaf968c1461007c57600080fd5b346103555780600319360112610355578151633fabe5a360e21b81526001600160a01b039060a08186817f00000000000000000000000086392dc19c0b719886221c78ab11eb8cf5c5281286165afa91821561034b578380878293839584976102e6575b506020908951928380926312aed41960e31b82527f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0165afa9081156102dc5783916102a7575b507f0000000000000000000000000000000000000000000000000de0b6b3a76400006001600160ff1b0384841385831381811684840487111661028057600160ff1b918785129190821687840586121661029357848888129305871290831616610280571682820585121661026d57821161025d576101a592026105b0565b907f000000000000000000000000000000000000000000000000000000000000000860ff167f000000000000000000000000000000000000000000000000000000000000001281811061024a570390604d8211610237575060a097509061020f91600a0a906105b0565b85516001600160501b0395861681526020810191909152948501526060840152166080820152f35b634e487b7160e01b815260118952602490fd5b634e487b7160e01b835260118a52602483fd5b885163e7e828ad60e01b81528a90fd5b634e487b7160e01b855260118b52602485fd5b634e487b7160e01b875260118d52602487fd5b50634e487b7160e01b875260118d52602487fd5b90506020813d82116102d4575b816102c16020938361055e565b810103126102d0575138610126565b8280fd5b3d91506102b4565b88513d85823e3d90fd5b95509550505093505060a0813d8211610343575b8161030760a0938361055e565b810103126102d05761031881610597565b9060208101519385820151876020610337608060608701519601610597565b959792949596906100e0565b3d91506102fa565b84513d85823e3d90fd5b80fd5b50903461039c578160031936011261039c57517f00000000000000000000000086392dc19c0b719886221c78ab11eb8cf5c528126001600160a01b03168152602090f35b5080fd5b50903461039c578160031936011261039c5780516103bf60608261055e565b602281526020907f437573746f6d207072696365206665656420666f7220777374455448202f204582820152610a8960f31b838201528251938285938452825192838286015282915b8483106104335750508210610427575b50601f01601f19168101030190f35b83828401015284610418565b81830181015188840188015287955091820191610408565b50903461039c578160031936011261039c576020905160018152f35b50903461039c578160031936011261039c57517f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca06001600160a01b03168152602090f35b50903461039c578160031936011261039c576020905160ff7f0000000000000000000000000000000000000000000000000000000000000008168152f35b50903461039c578160031936011261039c57602090517f00000000000000000000000000000000000000000000000000000000000000128152f35b90503461039c578160031936011261039c576020907f0000000000000000000000000000000000000000000000000de0b6b3a76400008152f35b601f909101601f19168101906001600160401b0382119082101761058157604052565b634e487b7160e01b600052604160045260246000fd5b51906001600160501b03821682036105ab57565b600080fd5b81156105e157600160ff1b81146000198314166105cb570590565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fdfea2646970667358221220b5b758bb8e82efba778ccf5fe66d27c2d2ed7a1e53dec147b6cedc5cd496875a64736f6c634300080f0033

Verified Source Code Full Match

Compiler: v0.8.15+commit.e14f2714 EVM: london
WstETHPriceFeed.sol 78 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.15;

import "./vendor/@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "./IPriceFeed.sol";
import "./IWstETH.sol";

/**
 * @title wstETH price feed
 * @notice A custom price feed that calculates the price for wstETH / ETH
 * @author Compound
 */
contract WstETHPriceFeed is IPriceFeed {
    /** Custom errors **/
    error BadDecimals();
    error InvalidInt256();

    /// @notice Version of the price feed
    uint public constant override version = 1;

    /// @notice Description of the price feed
    string public constant override description = "Custom price feed for wstETH / ETH";

    /// @notice Number of decimals for returned prices
    uint8 public immutable override decimals;

    /// @notice Chainlink stETH / ETH price feed
    address public immutable stETHtoETHPriceFeed;

    /// @notice Number of decimals for the stETH / ETH price feed
    uint public immutable stETHToETHPriceFeedDecimals;

    /// @notice WstETH contract address
    address public immutable wstETH;

    /// @notice Scale for WstETH contract
    int public immutable wstETHScale;

    constructor(address stETHtoETHPriceFeed_, address wstETH_, uint8 decimals_) {
        stETHtoETHPriceFeed = stETHtoETHPriceFeed_;
        stETHToETHPriceFeedDecimals = AggregatorV3Interface(stETHtoETHPriceFeed_).decimals();
        wstETH = wstETH_;
        // Note: Safe to convert directly to an int256 because wstETH.decimals == 18
        wstETHScale = int256(10 ** IWstETH(wstETH).decimals());

        // Note: stETH / ETH price feed has 18 decimals so `decimals_` should always be less than or equals to that
        if (decimals_ > stETHToETHPriceFeedDecimals) revert BadDecimals();
        decimals = decimals_;
    }

    function signed256(uint256 n) internal pure returns (int256) {
        if (n > uint256(type(int256).max)) revert InvalidInt256();
        return int256(n);
    }

    /**
     * @notice WstETH price for the latest round
     * @return roundId Round id from the stETH price feed
     * @return answer Latest price for wstETH / USD
     * @return startedAt Timestamp when the round was started; passed on from stETH price feed
     * @return updatedAt Timestamp when the round was last updated; passed on from stETH price feed
     * @return answeredInRound Round id in which the answer was computed; passed on from stETH price feed
     **/
    function latestRoundData() override external view returns (
        uint80 roundId,
        int256 answer,
        uint256 startedAt,
        uint256 updatedAt,
        uint80 answeredInRound
    ) {
        (uint80 roundId_, int256 stETHPrice, uint256 startedAt_, uint256 updatedAt_, uint80 answeredInRound_) = AggregatorV3Interface(stETHtoETHPriceFeed).latestRoundData();
        uint256 tokensPerStEth = IWstETH(wstETH).tokensPerStEth();
        int256 price = stETHPrice * wstETHScale / signed256(tokensPerStEth);
        // Note: The stETH price feed should always have an equal or larger amount of decimals than this price feed (enforced by validation in constructor)
        int256 scaledPrice = price / int256(10 ** (stETHToETHPriceFeedDecimals - decimals));
        return (roundId_, scaledPrice, startedAt_, updatedAt_, answeredInRound_);
    }
}
IPriceFeed.sol 25 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.15;

/**
 * @dev Interface for price feeds used by Comet
 * Note This is Chainlink's AggregatorV3Interface, but without the `getRoundData` function.
 */
interface IPriceFeed {
  function decimals() external view returns (uint8);

  function description() external view returns (string memory);

  function version() external view returns (uint256);

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}
IWstETH.sol 23 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.15;

import "./ERC20.sol";

/**
 * @dev Interface for interacting with WstETH contract
 * Note Not a comprehensive interface
 */
interface IWstETH is ERC20 {
    function stETH() external returns (address);

    function wrap(uint256 _stETHAmount) external returns (uint256);
    function unwrap(uint256 _wstETHAmount) external returns (uint256);

    function receive() external payable;

    function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256);
    function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);

    function stEthPerToken() external view returns (uint256);
    function tokensPerStEth() external view returns (uint256);
}
AggregatorV3Interface.sol 35 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AggregatorV3Interface {
  function decimals() external view returns (uint8);

  function description() external view returns (string memory);

  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}
ERC20.sol 63 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.15;

/**
 * @title ERC 20 Token Standard Interface
 *  https://eips.ethereum.org/EIPS/eip-20
 */
interface ERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);

    /**
      * @notice Get the total number of tokens in circulation
      * @return The supply of tokens
      */
    function totalSupply() external view returns (uint256);

    /**
     * @notice Gets the balance of the specified address
     * @param owner The address from which the balance will be retrieved
     * @return The balance
     */
    function balanceOf(address owner) external view returns (uint256);

    /**
      * @notice Transfer `amount` tokens from `msg.sender` to `dst`
      * @param dst The address of the destination account
      * @param amount The number of tokens to transfer
      * @return Whether or not the transfer succeeded
      */
    function transfer(address dst, uint256 amount) external returns (bool);

    /**
      * @notice Transfer `amount` tokens from `src` to `dst`
      * @param src The address of the source account
      * @param dst The address of the destination account
      * @param amount The number of tokens to transfer
      * @return Whether or not the transfer succeeded
      */
    function transferFrom(address src, address dst, uint256 amount) external returns (bool);

    /**
      * @notice Approve `spender` to transfer up to `amount` from `src`
      * @dev This will overwrite the approval amount for `spender`
      *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
      * @param spender The address of the account which may transfer tokens
      * @param amount The number of tokens that are approved (-1 means infinite)
      * @return Whether or not the approval succeeded
      */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
      * @notice Get the current allowance from `owner` for `spender`
      * @param owner The address of the account which owns the tokens to be spent
      * @param spender The address of the account which may transfer tokens
      * @return The number of tokens allowed to be spent (-1 means infinite)
      */
    function allowance(address owner, address spender) external view returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
}

Read Contract

decimals 0x313ce567 → uint8
description 0x7284e416 → string
latestRoundData 0xfeaf968c → uint80, int256, uint256, uint256, uint80
stETHToETHPriceFeedDecimals 0x22c2b36c → uint256
stETHtoETHPriceFeed 0xed1a68d1 → address
version 0x54fd4d50 → uint256
wstETH 0x4aa07e64 → address
wstETHScale 0x17f098ca → int256

Recent Transactions

This address has 1 on-chain transactions, but only 1.4% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →