WstETHPriceFeed

Description:

Smart contract deployed on Ethereum with Factory, Oracle features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/oracle/priceFeeds/ethereum/WstETHPriceFeed.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "../../interfaces/IResilientOracle.sol";
import "../../libraries/FullMath.sol";
import { AggregatorV3Interface } from "../../interfaces/OracleInterface.sol";
import { IStEth } from "../../interfaces/IStEth.sol";

/**
 * @title WstETHPriceFeed
 * @dev This contract is used to get the price of price of wstETH/stETH from wstETH exchangeRate and ETH/USD from ResilientOracle
 */
contract WstETHPriceFeed {
  IResilientOracle public resilientOracle;
  address public constant WETH_TOKEN_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
  IStEth public constant ST_ETH = IStEth(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);

  /**
   * @dev Constructor
   * @param _resilientOracle The address of the Resilient Oracle contract
   */
  constructor(address _resilientOracle) {
    require(_resilientOracle != address(0), "Zero address provided");
    resilientOracle = IResilientOracle(_resilientOracle);
  }

  function decimals() external pure returns (uint8) {
    return 8;
  }

  function description() external pure returns (string memory) {
    return "wstETH Price Feed";
  }

  function version() external pure returns (uint256) {
    return 1;
  }

  function latestAnswer() external view returns (int256 answer) {
    // get price
    uint256 price = getPrice();
    // cast price to int256
    answer = int256(price);
  }

  function latestRoundData()
    external
    view
    returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
  {
    // get price
    uint256 _answer = getPrice();
    // mock timestamp to latest block timestamp
    uint256 timestamp = block.timestamp;
    // mock roundId to timestamp
    roundId = uint80(timestamp);
    return (roundId, int256(_answer), timestamp, timestamp, roundId);
  }

  /**
   * @dev Get the price of wstETH in 8 DPs
   *      wstETH/stETH from stETH contract and ETH/USD from ResilientOracle
   * @return price The price of wstETH in 8 decimals
   */
  function getPrice() private view returns (uint256 price) {
    // wstETH/stETH in 18 DPs
    uint256 exchangeRate = ST_ETH.getPooledEthByShares(1e18);

    // ETH/USD in 8 DPs
    uint256 ethPrice = resilientOracle.peek(WETH_TOKEN_ADDR);

    return FullMath.mulDiv(exchangeRate, ethPrice, 1e18);
  }
}
"
    },
    "contracts/oracle/interfaces/IResilientOracle.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IResilientOracle {
  function peek(address asset) external view returns (uint256);
}
"
    },
    "contracts/oracle/libraries/FullMath.sol": {
      "content": "// SPDX-License-Identifier: CC-BY-4.0
pragma solidity ^0.8.10;

// taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
// license is CC-BY-4.0
library FullMath {
  function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) {
  unchecked{
    uint256 mm = mulmod(x, y, type(uint256).max);
    l = x * y;
    h = mm - l;
    if (mm < l) h -= 1;
  }
  }

  function fullDiv(
    uint256 l,
    uint256 h,
    uint256 d
  ) private pure returns (uint256) {
  unchecked {
    uint256 pow2 = d & (~d + 1);
    d /= pow2;
    l /= pow2;
    l += h * ((~pow2 + 1) / pow2 + 1);
    uint256 r = 1;
    r *= 2 - d * r;
    r *= 2 - d * r;
    r *= 2 - d * r;
    r *= 2 - d * r;
    r *= 2 - d * r;
    r *= 2 - d * r;
    r *= 2 - d * r;
    r *= 2 - d * r;
    return l * r;
  }
  }

  function mulDiv(
    uint256 x,
    uint256 y,
    uint256 d
  ) internal pure returns (uint256) {
    (uint256 l, uint256 h) = fullMul(x, y);

    unchecked {
      uint256 mm = mulmod(x, y, d);
      if (mm > l) h -= 1;
      l -= mm;

      if (h == 0) return l / d;

      require(h < d, "FullMath: FULLDIV_OVERFLOW");
      return fullDiv(l, h, d);
    }
  }

  /// @notice ported from https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/FullMath.sol
  function mulDivRoundingUp(
      uint256 a,
      uint256 b,
      uint256 denominator
  ) internal pure returns (uint256 result) {
      result = mulDiv(a, b, denominator);
      if (mulmod(a, b, denominator) > 0) {
          require(result < type(uint256).max);
          result++;
      }
  }
}
"
    },
    "contracts/oracle/interfaces/OracleInterface.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface OracleInterface {
  function peek(address asset) external view returns (uint256);
}

interface IAPI3Proxy {
  function read()
  external
  view
  returns (int224 value, uint32 timestamp);
}

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

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

  function version() external view returns (uint256);

  function latestAnswer() external view returns (int256);

  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
  );
}

interface BoundValidatorInterface {
  function validatePriceWithAnchorPrice(
    address asset,
    uint256 reporterPrice,
    uint256 anchorPrice
  ) external view returns (bool);
}

"
    },
    "contracts/oracle/interfaces/IStEth.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IStEth {
  function getPooledEthByShares(uint256) external view returns (uint256);
}
"
    }
  },
  "settings": {
    "remappings": [
      "@chainlink/=node_modules/@chainlink/",
      "@openzeppelin/=node_modules/@openzeppelin/",
      "@pythnetwork/=node_modules/@pythnetwork/",
      "eth-gas-reporter/=node_modules/eth-gas-reporter/",
      "forge-std/=lib/forge-std/src/",
      "hardhat/=node_modules/hardhat/"
    ],
    "optimizer": {
      "enabled": true,
      "runs": 100
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs"
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "london",
    "viaIR": false
  }
}}

Tags:
Factory, Oracle|addr:0x36b0ae9841c68db46d8435760680134089ce166d|verified:true|block:23460688|tx:0x2634acbfde5510ba2c08e25fa095bcb4c5946795ed63afdee87a4c31f944910f|first_check:1759053247

Submitted on: 2025-09-28 11:54:07

Comments

Log in to comment.

No comments yet.