From 1e35d16fef6b404d32256f851f5061ae89c1f68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Ace=C3=B1olaza?= Date: Wed, 1 Oct 2025 17:40:10 -0300 Subject: [PATCH 1/2] Adds KHYPEApi3ReaderProxyV1 and WstHYPEApi3ReaderProxyV1 adapter contracts --- contracts/KHYPEApi3ReaderProxyV1.sol | 43 ++++++++++++++++++++++ contracts/WstHYPEApi3ReaderProxyV1.sol | 51 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 contracts/KHYPEApi3ReaderProxyV1.sol create mode 100644 contracts/WstHYPEApi3ReaderProxyV1.sol diff --git a/contracts/KHYPEApi3ReaderProxyV1.sol b/contracts/KHYPEApi3ReaderProxyV1.sol new file mode 100644 index 0000000..cdf10b2 --- /dev/null +++ b/contracts/KHYPEApi3ReaderProxyV1.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import "@api3/contracts/interfaces/IApi3ReaderProxy.sol"; + +// Minimal interface for StakingAccountant +interface IStakingAccountant { + function kHYPEToHYPE(uint256 kHYPEAmount) external view returns (uint256); +} + +/// @title An immutable proxy contract that reads the kHYPE/HYPE exchange rate on +/// the HyperEVM network. +/// from the StakingAccountant contract. +/// @dev This contract implements only the IApi3ReaderProxy and not the +/// AggregatorV2V3Interface which is usually implemented with Api3 proxies. The +/// user of this contract needs to be aware of this and only use this contract +/// where the IApi3ReaderProxy interface is expected. +contract KHYPEApi3ReaderProxyV1 is IApi3ReaderProxy { + /// @dev Address of the StakingAccountant contract. This address belongs to + /// the deployment on HyperEVM chain. + IStakingAccountant public constant STAKING_ACCOUNTANT = + IStakingAccountant(0x9209648Ec9D448EF57116B73A2f081835643dc7A); + + /// @inheritdoc IApi3ReaderProxy + /// @dev The value returned by this function is the HYPE amount for 1 kHYPE, + /// scaled to 18 decimals. The timestamp returned is the current block + /// timestamp. + function read() + public + view + override + returns (int224 value, uint32 timestamp) + { + // The kHYPEToHYPE function returns the amount of HYPE for a given amount + // of kHYPE. + // 1e18 is passed (representing 1 kHYPE, as it has 18 decimals) to get + // the rate. + uint256 HYPEPerKHYPE = STAKING_ACCOUNTANT.kHYPEToHYPE(1e18); + + value = int224(int256(HYPEPerKHYPE)); + timestamp = uint32(block.timestamp); + } +} diff --git a/contracts/WstHYPEApi3ReaderProxyV1.sol b/contracts/WstHYPEApi3ReaderProxyV1.sol new file mode 100644 index 0000000..3dd69a1 --- /dev/null +++ b/contracts/WstHYPEApi3ReaderProxyV1.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import "@api3/contracts/interfaces/IApi3ReaderProxy.sol"; + +// Minimal interface for wstHYPE +interface IWstHYPE { + function sthype() external view returns (address); +} + +// Minimal interface for stHYPE +interface IStHYPE { + function sharesToBalance(uint256 shares) external view returns (uint256); +} + +/// @title An immutable proxy contract that reads the wstHYPE/stHYPE exchange +/// rate on the HyperEVM network. +/// @dev This contract implements only the IApi3ReaderProxy and not the +/// AggregatorV2V3Interface which is usually implemented with Api3 proxies. The +/// user of this contract needs to be aware of this and only use this contract +/// where the IApi3ReaderProxy interface is expected. +contract WstHYPEApi3ReaderProxyV1 is IApi3ReaderProxy { + /// @dev Address of the wstHYPE contract. This address belongs to the + /// deployment on HyperEVM chain. + IWstHYPE public constant WST_HYPE = + IWstHYPE(0x94e8396e0869c9F2200760aF0621aFd240E1CF38); + + /// @inheritdoc IApi3ReaderProxy + /// @dev The value returned by this function is the stHYPE amount for 1 + /// wstHYPE, scaled to 18 decimals. The timestamp returned is the current + /// block timestamp. + function read() + public + view + override + returns (int224 value, uint32 timestamp) + { + address stHYPEAddress = WST_HYPE.sthype(); + + // The logic is analogous to wstETH's stEthPerToken(), which returns + // stETH.getPooledEthByShares(1 ether). + // Here, it is assumed 1 wstHYPE corresponds to 1e24 shares of stHYPE, as + // stHYPE shares have 24 decimals. + // These shares are then converted to a balance of stHYPE (which has 18 + // decimals). + uint256 stHYPEPerToken = IStHYPE(stHYPEAddress).sharesToBalance(1e24); + + value = int224(int256(stHYPEPerToken)); + timestamp = uint32(block.timestamp); + } +} From 75422982a5c7a6d3ffef2d5e834481dfb75ed7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Ace=C3=B1olaza?= Date: Thu, 2 Oct 2025 08:44:34 -0300 Subject: [PATCH 2/2] Fixes title natspec comment on KHYPEApi3ReaderProxyV1 --- contracts/KHYPEApi3ReaderProxyV1.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/KHYPEApi3ReaderProxyV1.sol b/contracts/KHYPEApi3ReaderProxyV1.sol index cdf10b2..3dc1ca3 100644 --- a/contracts/KHYPEApi3ReaderProxyV1.sol +++ b/contracts/KHYPEApi3ReaderProxyV1.sol @@ -8,8 +8,7 @@ interface IStakingAccountant { function kHYPEToHYPE(uint256 kHYPEAmount) external view returns (uint256); } -/// @title An immutable proxy contract that reads the kHYPE/HYPE exchange rate on -/// the HyperEVM network. +/// @title An immutable proxy contract that reads the kHYPE/HYPE exchange rate /// from the StakingAccountant contract. /// @dev This contract implements only the IApi3ReaderProxy and not the /// AggregatorV2V3Interface which is usually implemented with Api3 proxies. The