From f1651636b79a2130974afba41eceb073c3dcac30 Mon Sep 17 00:00:00 2001 From: Debugger022 Date: Thu, 8 Jan 2026 17:42:44 +0530 Subject: [PATCH 1/6] feat: deploy stable usdt price feed --- contracts/oracles/StableUsdtPriceFeed.sol | 65 ++++++ deploy/26-deploy-stable-usdt-price-feed.ts | 30 +++ .../bscmainnet/StableUsdtPriceFeed.json | 206 ++++++++++++++++++ .../3783e79f330d89bf7845ddf14f4fec22.json | 40 ++++ 4 files changed, 341 insertions(+) create mode 100644 contracts/oracles/StableUsdtPriceFeed.sol create mode 100644 deploy/26-deploy-stable-usdt-price-feed.ts create mode 100644 deployments/bscmainnet/StableUsdtPriceFeed.json create mode 100644 deployments/bscmainnet/solcInputs/3783e79f330d89bf7845ddf14f4fec22.json diff --git a/contracts/oracles/StableUsdtPriceFeed.sol b/contracts/oracles/StableUsdtPriceFeed.sol new file mode 100644 index 00000000..1aefacce --- /dev/null +++ b/contracts/oracles/StableUsdtPriceFeed.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { ResilientOracleInterface } from "../interfaces/OracleInterface.sol"; + +/** + * @title StableUsdtPriceFeed + * @dev This contract is used to get the price of USDT from a Resilient Oracle + * and bounds the price to a certain range. + */ +contract StableUsdtPriceFeed { + ResilientOracleInterface public resilientOracle; + + address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955; + uint256 public constant UPPER_BOUND = 102000000; // 1.02 USD + uint256 public constant LOWER_BOUND = 98000000; // 0.98 USD + + constructor(address _resilientOracle) { + require(_resilientOracle != address(0), "Zero address provided"); + resilientOracle = ResilientOracleInterface(_resilientOracle); + } + + 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); + } + + function decimals() external pure returns (uint8) { + return 8; + } + + function description() external pure returns (string memory) { + return "Stabilized USDT Price Feed"; + } + + function version() external pure returns (uint256) { + return 1; + } + + /** + * @dev Get the price from the Resilient Oracle, and bound it to the range + * @return price The price of USDT in 8 decimals + */ + function getPrice() private view returns (uint256 price) { + // get USDT price (8 decimals) + price = resilientOracle.getPrice(USDT_TOKEN_ADDR); + price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price); + } +} diff --git a/deploy/26-deploy-stable-usdt-price-feed.ts b/deploy/26-deploy-stable-usdt-price-feed.ts new file mode 100644 index 00000000..8c0a2f6a --- /dev/null +++ b/deploy/26-deploy-stable-usdt-price-feed.ts @@ -0,0 +1,30 @@ +import hre from "hardhat"; +import { DeployFunction } from "hardhat-deploy/dist/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +const func: DeployFunction = async function ({ getNamedAccounts, deployments }: HardhatRuntimeEnvironment) { + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + // Get the ResilientOracle contract + const resilientOracle = await hre.ethers.getContract("ResilientOracle"); + + await deploy("StableUsdtPriceFeed", { + contract: "StableUsdtPriceFeed", + from: deployer, + log: true, + deterministicDeployment: false, + skipIfAlreadyDeployed: true, + args: [resilientOracle.address], + }); + + const stableUsdtPriceFeed = await hre.ethers.getContract("StableUsdtPriceFeed"); + console.log(`StableUsdtPriceFeed deployed at: ${stableUsdtPriceFeed.address}`); + console.log(`Resilient Oracle address: ${resilientOracle.address}`); +}; + +func.tags = ["stable-usdt-price-feed"]; +func.skip = async (hr: HardhatRuntimeEnvironment) => + hr.network.name !== "bscmainnet" && hr.network.name !== "bsctestnet"; + +export default func; diff --git a/deployments/bscmainnet/StableUsdtPriceFeed.json b/deployments/bscmainnet/StableUsdtPriceFeed.json new file mode 100644 index 00000000..e3a80a90 --- /dev/null +++ b/deployments/bscmainnet/StableUsdtPriceFeed.json @@ -0,0 +1,206 @@ +{ + "address": "0x28d5A3358686d82E837BaaF225A4Faa418065532", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_resilientOracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LOWER_BOUND", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPPER_BOUND", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDT_TOKEN_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "latestAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "answer", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resilientOracle", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xfe120030ab8595897e7a738e768096c534b5d0a1b0841d8d540056b79ef7b214", + "receipt": { + "to": null, + "from": "0x24c30C9C84b8a3C71A521ad30007ED47372331b3", + "contractAddress": "0x28d5A3358686d82E837BaaF225A4Faa418065532", + "transactionIndex": 91, + "gasUsed": "244132", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x432b14657f5528440e13bdd992c3e0e397fdfc380d5b38a40dc32b4054d98f03", + "transactionHash": "0xfe120030ab8595897e7a738e768096c534b5d0a1b0841d8d540056b79ef7b214", + "logs": [], + "blockNumber": 74494438, + "cumulativeGasUsed": "18622283", + "status": 1, + "byzantium": true + }, + "args": ["0x6592b5DE802159F3E74B2486b091D11a8256ab8A"], + "numDeployments": 1, + "solcInputHash": "3783e79f330d89bf7845ddf14f4fec22", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_resilientOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LOWER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPPER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDT_TOKEN_ADDR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resilientOracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"StableUsdtPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/StableUsdtPriceFeed.sol\":\"StableUsdtPriceFeed\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/StableUsdtPriceFeed.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"../interfaces/OracleInterface.sol\\\";\\n\\n/**\\n * @title StableUsdtPriceFeed\\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\\n * and bounds the price to a certain range.\\n */\\ncontract StableUsdtPriceFeed {\\n\\n ResilientOracleInterface public resilientOracle;\\n\\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\\n uint256 public constant UPPER_BOUND = 102000000; // 1.02 USD\\n uint256 public constant LOWER_BOUND = 98000000; // 0.98 USD\\n\\n constructor(address _resilientOracle) {\\n require(_resilientOracle != address(0), \\\"Zero address provided\\\");\\n resilientOracle = ResilientOracleInterface(_resilientOracle);\\n }\\n\\n function decimals() external pure returns (uint8) {\\n return 8;\\n }\\n\\n function description() external pure returns (string memory) {\\n return \\\"Stabilized USDT Price Feed\\\";\\n }\\n\\n function version() external pure returns (uint256) {\\n return 1;\\n }\\n\\n function latestAnswer() external view returns (int256 answer) {\\n // get price\\n uint256 price = getPrice();\\n // cast price to int256\\n answer = int256(price);\\n }\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n ) {\\n // get price\\n uint256 _answer = getPrice();\\n // mock timestamp to latest block timestamp\\n uint256 timestamp = block.timestamp;\\n // mock roundId to timestamp\\n roundId = uint80(timestamp);\\n return (\\n roundId,\\n int256(_answer),\\n timestamp,\\n timestamp,\\n roundId\\n );\\n }\\n\\n /**\\n * @dev Get the price from the Resilient Oracle, and bound it to the range\\n * @return price The price of USDT in 8 decimals\\n */\\n function getPrice() private view returns (uint256 price) {\\n // get USDT price (8 decimals)\\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\\n }\\n\\n}\",\"keccak256\":\"0xaaa89506e630a3ca3ad9f7501585735e950fab3bee3cdad9470c2095cf3b5d5a\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x6080604052348015600e575f80fd5b506040516103db3803806103db833981016040819052602b9160a7565b6001600160a01b03811660845760405162461bcd60e51b815260206004820152601560248201527f5a65726f20616464726573732070726f76696465640000000000000000000000604482015260640160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560d2565b5f6020828403121560b6575f80fd5b81516001600160a01b038116811460cb575f80fd5b9392505050565b6102fc806100df5f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fa5780638d1d47f114610139578063de719b7614610154578063feaf968c1461015f575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b061019e565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b06305d75c8081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f919061027a565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0630614658081565b6101676101ae565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101a86101cf565b92915050565b5f805f805f806101bc6101cf565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906102af565b90506305d75c80811061027157630614658081116102685790565b50630614658090565b506305d75c8090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102bf575f80fd5b505191905056fea264697066735822122041743897cf8ba80404ab6f74662ab1a8ad94033eb7319b4bce9a152452bdfc5f64736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fa5780638d1d47f114610139578063de719b7614610154578063feaf968c1461015f575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b061019e565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b06305d75c8081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f919061027a565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0630614658081565b6101676101ae565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101a86101cf565b92915050565b5f805f805f806101bc6101cf565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906102af565b90506305d75c80811061027157630614658081116102685790565b50630614658090565b506305d75c8090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102bf575f80fd5b505191905056fea264697066735822122041743897cf8ba80404ab6f74662ab1a8ad94033eb7319b4bce9a152452bdfc5f64736f6c63430008190033", + "devdoc": { + "details": "This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.", + "kind": "dev", + "methods": {}, + "title": "StableUsdtPriceFeed", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 49, + "contract": "contracts/oracles/StableUsdtPriceFeed.sol:StableUsdtPriceFeed", + "label": "resilientOracle", + "offset": 0, + "slot": "0", + "type": "t_contract(ResilientOracleInterface)29" + } + ], + "types": { + "t_contract(ResilientOracleInterface)29": { + "encoding": "inplace", + "label": "contract ResilientOracleInterface", + "numberOfBytes": "20" + } + } + } +} diff --git a/deployments/bscmainnet/solcInputs/3783e79f330d89bf7845ddf14f4fec22.json b/deployments/bscmainnet/solcInputs/3783e79f330d89bf7845ddf14f4fec22.json new file mode 100644 index 00000000..058187d5 --- /dev/null +++ b/deployments/bscmainnet/solcInputs/3783e79f330d89bf7845ddf14f4fec22.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "contracts/oracles/StableUsdtPriceFeed.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ResilientOracleInterface } from \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title StableUsdtPriceFeed\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\n * and bounds the price to a certain range.\n */\ncontract StableUsdtPriceFeed {\n\n ResilientOracleInterface public resilientOracle;\n\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\n uint256 public constant UPPER_BOUND = 102000000; // 1.02 USD\n uint256 public constant LOWER_BOUND = 98000000; // 0.98 USD\n\n constructor(address _resilientOracle) {\n require(_resilientOracle != address(0), \"Zero address provided\");\n resilientOracle = ResilientOracleInterface(_resilientOracle);\n }\n\n function decimals() external pure returns (uint8) {\n return 8;\n }\n\n function description() external pure returns (string memory) {\n return \"Stabilized USDT Price Feed\";\n }\n\n function version() external pure returns (uint256) {\n return 1;\n }\n\n function latestAnswer() external view returns (int256 answer) {\n // get price\n uint256 price = getPrice();\n // cast price to int256\n answer = int256(price);\n }\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n ) {\n // get price\n uint256 _answer = getPrice();\n // mock timestamp to latest block timestamp\n uint256 timestamp = block.timestamp;\n // mock roundId to timestamp\n roundId = uint80(timestamp);\n return (\n roundId,\n int256(_answer),\n timestamp,\n timestamp,\n roundId\n );\n }\n\n /**\n * @dev Get the price from the Resilient Oracle, and bound it to the range\n * @return price The price of USDT in 8 decimals\n */\n function getPrice() private view returns (uint256 price) {\n // get USDT price (8 decimals)\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\n }\n\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} From e62750a1037f0fb948d186e8dae45e50c6619140 Mon Sep 17 00:00:00 2001 From: Debugger022 <104391977+Debugger022@users.noreply.github.com> Date: Thu, 8 Jan 2026 12:18:01 +0000 Subject: [PATCH 2/6] feat: updating deployment files --- deployments/bscmainnet.json | 153 ++++++++++++++++++++++++++ deployments/bscmainnet_addresses.json | 1 + 2 files changed, 154 insertions(+) diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index dae67d41..9b43697f 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -14512,6 +14512,159 @@ } ] }, + "StableUsdtPriceFeed": { + "address": "0x28d5A3358686d82E837BaaF225A4Faa418065532", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_resilientOracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LOWER_BOUND", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPPER_BOUND", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDT_TOKEN_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "latestAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "answer", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resilientOracle", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ] + }, "StkBNBOracle": { "address": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6", "abi": [ diff --git a/deployments/bscmainnet_addresses.json b/deployments/bscmainnet_addresses.json index 391276cb..485ae439 100644 --- a/deployments/bscmainnet_addresses.json +++ b/deployments/bscmainnet_addresses.json @@ -48,6 +48,7 @@ "SolvBTC.BBN_OneJumpRedStoneOracle": "0x98B9bC5a1e7E439ebEB0BEdB7e9f6b24fEc1E8B4", "SolvBTC.BBN_OneJumpRedStoneOracle_Implementation": "0x98eD7290a3D52FA5639dd76C16ADE3074ba664dd", "SolvBTC.BBN_OneJumpRedStoneOracle_Proxy": "0x98B9bC5a1e7E439ebEB0BEdB7e9f6b24fEc1E8B4", + "StableUsdtPriceFeed": "0x28d5A3358686d82E837BaaF225A4Faa418065532", "StkBNBOracle": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6", "StkBNBOracle_Implementation": "0xA7C432c50D310c805c8342488921A108b585397F", "StkBNBOracle_Proxy": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6", From d3271a55748a83ef4dfe2f00149ad3cc2dec6750 Mon Sep 17 00:00:00 2001 From: Debugger022 Date: Thu, 8 Jan 2026 20:04:56 +0530 Subject: [PATCH 3/6] refactor: update bounds in StableUsdtPriceFeed --- contracts/oracles/StableUsdtPriceFeed.sol | 8 ++-- .../bscmainnet/StableUsdtPriceFeed.json | 28 ++++++------- .../7662c78da4eeb92ea0be37cb6d15b86b.json | 40 +++++++++++++++++++ 3 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 deployments/bscmainnet/solcInputs/7662c78da4eeb92ea0be37cb6d15b86b.json diff --git a/contracts/oracles/StableUsdtPriceFeed.sol b/contracts/oracles/StableUsdtPriceFeed.sol index 1aefacce..b8273edb 100644 --- a/contracts/oracles/StableUsdtPriceFeed.sol +++ b/contracts/oracles/StableUsdtPriceFeed.sol @@ -12,8 +12,8 @@ contract StableUsdtPriceFeed { ResilientOracleInterface public resilientOracle; address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955; - uint256 public constant UPPER_BOUND = 102000000; // 1.02 USD - uint256 public constant LOWER_BOUND = 98000000; // 0.98 USD + uint256 public constant UPPER_BOUND = 1020000000000000000; // 1.02 USD + uint256 public constant LOWER_BOUND = 980000000000000000; // 0.98 USD constructor(address _resilientOracle) { require(_resilientOracle != address(0), "Zero address provided"); @@ -55,10 +55,10 @@ contract StableUsdtPriceFeed { /** * @dev Get the price from the Resilient Oracle, and bound it to the range - * @return price The price of USDT in 8 decimals + * @return price The price of USDT in 18 decimals */ function getPrice() private view returns (uint256 price) { - // get USDT price (8 decimals) + // get USDT price (18 decimals) price = resilientOracle.getPrice(USDT_TOKEN_ADDR); price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price); } diff --git a/deployments/bscmainnet/StableUsdtPriceFeed.json b/deployments/bscmainnet/StableUsdtPriceFeed.json index e3a80a90..cd901b49 100644 --- a/deployments/bscmainnet/StableUsdtPriceFeed.json +++ b/deployments/bscmainnet/StableUsdtPriceFeed.json @@ -1,5 +1,5 @@ { - "address": "0x28d5A3358686d82E837BaaF225A4Faa418065532", + "address": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", "abi": [ { "inputs": [ @@ -150,28 +150,28 @@ "type": "function" } ], - "transactionHash": "0xfe120030ab8595897e7a738e768096c534b5d0a1b0841d8d540056b79ef7b214", + "transactionHash": "0x2d3f051a23af7e5a8d130f71e93abd024effca7def8ac5b2fc5ba57dd08dba2f", "receipt": { "to": null, "from": "0x24c30C9C84b8a3C71A521ad30007ED47372331b3", - "contractAddress": "0x28d5A3358686d82E837BaaF225A4Faa418065532", - "transactionIndex": 91, - "gasUsed": "244132", + "contractAddress": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", + "transactionIndex": 100, + "gasUsed": "249180", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x432b14657f5528440e13bdd992c3e0e397fdfc380d5b38a40dc32b4054d98f03", - "transactionHash": "0xfe120030ab8595897e7a738e768096c534b5d0a1b0841d8d540056b79ef7b214", + "blockHash": "0x520074cd542a4b62d2b1c315271b8e8e8b5e499192fa74d02d390799a89b0174", + "transactionHash": "0x2d3f051a23af7e5a8d130f71e93abd024effca7def8ac5b2fc5ba57dd08dba2f", "logs": [], - "blockNumber": 74494438, - "cumulativeGasUsed": "18622283", + "blockNumber": 74506610, + "cumulativeGasUsed": "19514274", "status": 1, "byzantium": true }, "args": ["0x6592b5DE802159F3E74B2486b091D11a8256ab8A"], - "numDeployments": 1, - "solcInputHash": "3783e79f330d89bf7845ddf14f4fec22", - "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_resilientOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LOWER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPPER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDT_TOKEN_ADDR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resilientOracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"StableUsdtPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/StableUsdtPriceFeed.sol\":\"StableUsdtPriceFeed\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/StableUsdtPriceFeed.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"../interfaces/OracleInterface.sol\\\";\\n\\n/**\\n * @title StableUsdtPriceFeed\\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\\n * and bounds the price to a certain range.\\n */\\ncontract StableUsdtPriceFeed {\\n\\n ResilientOracleInterface public resilientOracle;\\n\\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\\n uint256 public constant UPPER_BOUND = 102000000; // 1.02 USD\\n uint256 public constant LOWER_BOUND = 98000000; // 0.98 USD\\n\\n constructor(address _resilientOracle) {\\n require(_resilientOracle != address(0), \\\"Zero address provided\\\");\\n resilientOracle = ResilientOracleInterface(_resilientOracle);\\n }\\n\\n function decimals() external pure returns (uint8) {\\n return 8;\\n }\\n\\n function description() external pure returns (string memory) {\\n return \\\"Stabilized USDT Price Feed\\\";\\n }\\n\\n function version() external pure returns (uint256) {\\n return 1;\\n }\\n\\n function latestAnswer() external view returns (int256 answer) {\\n // get price\\n uint256 price = getPrice();\\n // cast price to int256\\n answer = int256(price);\\n }\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n ) {\\n // get price\\n uint256 _answer = getPrice();\\n // mock timestamp to latest block timestamp\\n uint256 timestamp = block.timestamp;\\n // mock roundId to timestamp\\n roundId = uint80(timestamp);\\n return (\\n roundId,\\n int256(_answer),\\n timestamp,\\n timestamp,\\n roundId\\n );\\n }\\n\\n /**\\n * @dev Get the price from the Resilient Oracle, and bound it to the range\\n * @return price The price of USDT in 8 decimals\\n */\\n function getPrice() private view returns (uint256 price) {\\n // get USDT price (8 decimals)\\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\\n }\\n\\n}\",\"keccak256\":\"0xaaa89506e630a3ca3ad9f7501585735e950fab3bee3cdad9470c2095cf3b5d5a\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", - "bytecode": "0x6080604052348015600e575f80fd5b506040516103db3803806103db833981016040819052602b9160a7565b6001600160a01b03811660845760405162461bcd60e51b815260206004820152601560248201527f5a65726f20616464726573732070726f76696465640000000000000000000000604482015260640160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560d2565b5f6020828403121560b6575f80fd5b81516001600160a01b038116811460cb575f80fd5b9392505050565b6102fc806100df5f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fa5780638d1d47f114610139578063de719b7614610154578063feaf968c1461015f575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b061019e565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b06305d75c8081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f919061027a565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0630614658081565b6101676101ae565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101a86101cf565b92915050565b5f805f805f806101bc6101cf565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906102af565b90506305d75c80811061027157630614658081116102685790565b50630614658090565b506305d75c8090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102bf575f80fd5b505191905056fea264697066735822122041743897cf8ba80404ab6f74662ab1a8ad94033eb7319b4bce9a152452bdfc5f64736f6c63430008190033", - "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fa5780638d1d47f114610139578063de719b7614610154578063feaf968c1461015f575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b061019e565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b06305d75c8081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f919061027a565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0630614658081565b6101676101ae565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101a86101cf565b92915050565b5f805f805f806101bc6101cf565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906102af565b90506305d75c80811061027157630614658081116102685790565b50630614658090565b506305d75c8090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102bf575f80fd5b505191905056fea264697066735822122041743897cf8ba80404ab6f74662ab1a8ad94033eb7319b4bce9a152452bdfc5f64736f6c63430008190033", + "numDeployments": 2, + "solcInputHash": "7662c78da4eeb92ea0be37cb6d15b86b", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_resilientOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LOWER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPPER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDT_TOKEN_ADDR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resilientOracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"StableUsdtPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/StableUsdtPriceFeed.sol\":\"StableUsdtPriceFeed\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/StableUsdtPriceFeed.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"../interfaces/OracleInterface.sol\\\";\\n\\n/**\\n * @title StableUsdtPriceFeed\\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\\n * and bounds the price to a certain range.\\n */\\ncontract StableUsdtPriceFeed {\\n ResilientOracleInterface public resilientOracle;\\n\\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\\n uint256 public constant UPPER_BOUND = 1020000000000000000; // 1.02 USD\\n uint256 public constant LOWER_BOUND = 980000000000000000; // 0.98 USD\\n\\n constructor(address _resilientOracle) {\\n require(_resilientOracle != address(0), \\\"Zero address provided\\\");\\n resilientOracle = ResilientOracleInterface(_resilientOracle);\\n }\\n\\n function latestAnswer() external view returns (int256 answer) {\\n // get price\\n uint256 price = getPrice();\\n // cast price to int256\\n answer = int256(price);\\n }\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\\n {\\n // get price\\n uint256 _answer = getPrice();\\n // mock timestamp to latest block timestamp\\n uint256 timestamp = block.timestamp;\\n // mock roundId to timestamp\\n roundId = uint80(timestamp);\\n return (roundId, int256(_answer), timestamp, timestamp, roundId);\\n }\\n\\n function decimals() external pure returns (uint8) {\\n return 8;\\n }\\n\\n function description() external pure returns (string memory) {\\n return \\\"Stabilized USDT Price Feed\\\";\\n }\\n\\n function version() external pure returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev Get the price from the Resilient Oracle, and bound it to the range\\n * @return price The price of USDT in 18 decimals\\n */\\n function getPrice() private view returns (uint256 price) {\\n // get USDT price (18 decimals)\\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\\n }\\n}\\n\",\"keccak256\":\"0x76d853b410f934fb1803bc03b13430d65e6881a7cb1b797455b870f3e81a26ce\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x6080604052348015600e575f80fd5b506040516103f33803806103f3833981016040819052602b9160a7565b6001600160a01b03811660845760405162461bcd60e51b815260206004820152601560248201527f5a65726f20616464726573732070726f76696465640000000000000000000000604482015260640160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560d2565b5f6020828403121560b6575f80fd5b81516001600160a01b038116811460cb575f80fd5b9392505050565b610314806100df5f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fe5780638d1d47f11461013d578063de719b7614610158578063feaf968c14610167575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b06101a6565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b0670d99a8cec7e2000081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f9190610292565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0670e27c49886e6000081565b61016f6101b6565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101b06101d7565b92915050565b5f805f805f806101c46101d7565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610231573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025591906102c7565b9050670d99a8cec7e20000811061028557670e27c49886e6000081116102785790565b50670e27c49886e6000090565b50670d99a8cec7e2000090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102d7575f80fd5b505191905056fea26469706673582212209317360118d1fea857794e2c2c0975d179def70482934438fa3aa8b36cfe12a864736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fe5780638d1d47f11461013d578063de719b7614610158578063feaf968c14610167575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b06101a6565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b0670d99a8cec7e2000081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f9190610292565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0670e27c49886e6000081565b61016f6101b6565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101b06101d7565b92915050565b5f805f805f806101c46101d7565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610231573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025591906102c7565b9050670d99a8cec7e20000811061028557670e27c49886e6000081116102785790565b50670e27c49886e6000090565b50670d99a8cec7e2000090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102d7575f80fd5b505191905056fea26469706673582212209317360118d1fea857794e2c2c0975d179def70482934438fa3aa8b36cfe12a864736f6c63430008190033", "devdoc": { "details": "This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.", "kind": "dev", diff --git a/deployments/bscmainnet/solcInputs/7662c78da4eeb92ea0be37cb6d15b86b.json b/deployments/bscmainnet/solcInputs/7662c78da4eeb92ea0be37cb6d15b86b.json new file mode 100644 index 00000000..b48ea846 --- /dev/null +++ b/deployments/bscmainnet/solcInputs/7662c78da4eeb92ea0be37cb6d15b86b.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "contracts/oracles/StableUsdtPriceFeed.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ResilientOracleInterface } from \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title StableUsdtPriceFeed\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\n * and bounds the price to a certain range.\n */\ncontract StableUsdtPriceFeed {\n ResilientOracleInterface public resilientOracle;\n\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\n uint256 public constant UPPER_BOUND = 1020000000000000000; // 1.02 USD\n uint256 public constant LOWER_BOUND = 980000000000000000; // 0.98 USD\n\n constructor(address _resilientOracle) {\n require(_resilientOracle != address(0), \"Zero address provided\");\n resilientOracle = ResilientOracleInterface(_resilientOracle);\n }\n\n function latestAnswer() external view returns (int256 answer) {\n // get price\n uint256 price = getPrice();\n // cast price to int256\n answer = int256(price);\n }\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\n {\n // get price\n uint256 _answer = getPrice();\n // mock timestamp to latest block timestamp\n uint256 timestamp = block.timestamp;\n // mock roundId to timestamp\n roundId = uint80(timestamp);\n return (roundId, int256(_answer), timestamp, timestamp, roundId);\n }\n\n function decimals() external pure returns (uint8) {\n return 8;\n }\n\n function description() external pure returns (string memory) {\n return \"Stabilized USDT Price Feed\";\n }\n\n function version() external pure returns (uint256) {\n return 1;\n }\n\n /**\n * @dev Get the price from the Resilient Oracle, and bound it to the range\n * @return price The price of USDT in 18 decimals\n */\n function getPrice() private view returns (uint256 price) {\n // get USDT price (18 decimals)\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} From 52d2d4ca34f79d8b8e1f127585b6a3fd73eaa2ec Mon Sep 17 00:00:00 2001 From: Debugger022 <104391977+Debugger022@users.noreply.github.com> Date: Thu, 8 Jan 2026 14:36:49 +0000 Subject: [PATCH 4/6] feat: updating deployment files --- deployments/bscmainnet.json | 2 +- deployments/bscmainnet_addresses.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 9b43697f..a3cb4206 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -14513,7 +14513,7 @@ ] }, "StableUsdtPriceFeed": { - "address": "0x28d5A3358686d82E837BaaF225A4Faa418065532", + "address": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", "abi": [ { "inputs": [ diff --git a/deployments/bscmainnet_addresses.json b/deployments/bscmainnet_addresses.json index 485ae439..bcafeab5 100644 --- a/deployments/bscmainnet_addresses.json +++ b/deployments/bscmainnet_addresses.json @@ -48,7 +48,7 @@ "SolvBTC.BBN_OneJumpRedStoneOracle": "0x98B9bC5a1e7E439ebEB0BEdB7e9f6b24fEc1E8B4", "SolvBTC.BBN_OneJumpRedStoneOracle_Implementation": "0x98eD7290a3D52FA5639dd76C16ADE3074ba664dd", "SolvBTC.BBN_OneJumpRedStoneOracle_Proxy": "0x98B9bC5a1e7E439ebEB0BEdB7e9f6b24fEc1E8B4", - "StableUsdtPriceFeed": "0x28d5A3358686d82E837BaaF225A4Faa418065532", + "StableUsdtPriceFeed": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", "StkBNBOracle": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6", "StkBNBOracle_Implementation": "0xA7C432c50D310c805c8342488921A108b585397F", "StkBNBOracle_Proxy": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6", From bc10eafbc75a0fd5bffe405c0c6fd5dd3c884cf6 Mon Sep 17 00:00:00 2001 From: Debugger022 Date: Thu, 8 Jan 2026 21:59:03 +0530 Subject: [PATCH 5/6] refactor: update decimals --- contracts/oracles/StableUsdtPriceFeed.sol | 2 +- .../bscmainnet/StableUsdtPriceFeed.json | 26 ++++++------ .../18625204e1f090ab1a9c8ce54eea57c0.json | 40 +++++++++++++++++++ 3 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 deployments/bscmainnet/solcInputs/18625204e1f090ab1a9c8ce54eea57c0.json diff --git a/contracts/oracles/StableUsdtPriceFeed.sol b/contracts/oracles/StableUsdtPriceFeed.sol index b8273edb..4dfff7dc 100644 --- a/contracts/oracles/StableUsdtPriceFeed.sol +++ b/contracts/oracles/StableUsdtPriceFeed.sol @@ -42,7 +42,7 @@ contract StableUsdtPriceFeed { } function decimals() external pure returns (uint8) { - return 8; + return 18; } function description() external pure returns (string memory) { diff --git a/deployments/bscmainnet/StableUsdtPriceFeed.json b/deployments/bscmainnet/StableUsdtPriceFeed.json index cd901b49..3ae48d56 100644 --- a/deployments/bscmainnet/StableUsdtPriceFeed.json +++ b/deployments/bscmainnet/StableUsdtPriceFeed.json @@ -1,5 +1,5 @@ { - "address": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", + "address": "0xf373A7a76De77f7A86ea65BE15577AEA8bE02A36", "abi": [ { "inputs": [ @@ -150,28 +150,28 @@ "type": "function" } ], - "transactionHash": "0x2d3f051a23af7e5a8d130f71e93abd024effca7def8ac5b2fc5ba57dd08dba2f", + "transactionHash": "0x89795a751cb39e8b26218ebb17e70e6b119bc3fa43c19f75d9ae05af5e1cb42b", "receipt": { "to": null, "from": "0x24c30C9C84b8a3C71A521ad30007ED47372331b3", - "contractAddress": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", - "transactionIndex": 100, + "contractAddress": "0xf373A7a76De77f7A86ea65BE15577AEA8bE02A36", + "transactionIndex": 96, "gasUsed": "249180", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x520074cd542a4b62d2b1c315271b8e8e8b5e499192fa74d02d390799a89b0174", - "transactionHash": "0x2d3f051a23af7e5a8d130f71e93abd024effca7def8ac5b2fc5ba57dd08dba2f", + "blockHash": "0x80e6ebf36b4946c5402a277ee66b4cf639e024a7e733a4be5b17469b58c24d26", + "transactionHash": "0x89795a751cb39e8b26218ebb17e70e6b119bc3fa43c19f75d9ae05af5e1cb42b", "logs": [], - "blockNumber": 74506610, - "cumulativeGasUsed": "19514274", + "blockNumber": 74516176, + "cumulativeGasUsed": "13273162", "status": 1, "byzantium": true }, "args": ["0x6592b5DE802159F3E74B2486b091D11a8256ab8A"], - "numDeployments": 2, - "solcInputHash": "7662c78da4eeb92ea0be37cb6d15b86b", - "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_resilientOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LOWER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPPER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDT_TOKEN_ADDR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resilientOracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"StableUsdtPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/StableUsdtPriceFeed.sol\":\"StableUsdtPriceFeed\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/StableUsdtPriceFeed.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"../interfaces/OracleInterface.sol\\\";\\n\\n/**\\n * @title StableUsdtPriceFeed\\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\\n * and bounds the price to a certain range.\\n */\\ncontract StableUsdtPriceFeed {\\n ResilientOracleInterface public resilientOracle;\\n\\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\\n uint256 public constant UPPER_BOUND = 1020000000000000000; // 1.02 USD\\n uint256 public constant LOWER_BOUND = 980000000000000000; // 0.98 USD\\n\\n constructor(address _resilientOracle) {\\n require(_resilientOracle != address(0), \\\"Zero address provided\\\");\\n resilientOracle = ResilientOracleInterface(_resilientOracle);\\n }\\n\\n function latestAnswer() external view returns (int256 answer) {\\n // get price\\n uint256 price = getPrice();\\n // cast price to int256\\n answer = int256(price);\\n }\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\\n {\\n // get price\\n uint256 _answer = getPrice();\\n // mock timestamp to latest block timestamp\\n uint256 timestamp = block.timestamp;\\n // mock roundId to timestamp\\n roundId = uint80(timestamp);\\n return (roundId, int256(_answer), timestamp, timestamp, roundId);\\n }\\n\\n function decimals() external pure returns (uint8) {\\n return 8;\\n }\\n\\n function description() external pure returns (string memory) {\\n return \\\"Stabilized USDT Price Feed\\\";\\n }\\n\\n function version() external pure returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev Get the price from the Resilient Oracle, and bound it to the range\\n * @return price The price of USDT in 18 decimals\\n */\\n function getPrice() private view returns (uint256 price) {\\n // get USDT price (18 decimals)\\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\\n }\\n}\\n\",\"keccak256\":\"0x76d853b410f934fb1803bc03b13430d65e6881a7cb1b797455b870f3e81a26ce\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", - "bytecode": "0x6080604052348015600e575f80fd5b506040516103f33803806103f3833981016040819052602b9160a7565b6001600160a01b03811660845760405162461bcd60e51b815260206004820152601560248201527f5a65726f20616464726573732070726f76696465640000000000000000000000604482015260640160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560d2565b5f6020828403121560b6575f80fd5b81516001600160a01b038116811460cb575f80fd5b9392505050565b610314806100df5f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fe5780638d1d47f11461013d578063de719b7614610158578063feaf968c14610167575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b06101a6565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b0670d99a8cec7e2000081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f9190610292565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0670e27c49886e6000081565b61016f6101b6565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101b06101d7565b92915050565b5f805f805f806101c46101d7565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610231573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025591906102c7565b9050670d99a8cec7e20000811061028557670e27c49886e6000081116102785790565b50670e27c49886e6000090565b50670d99a8cec7e2000090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102d7575f80fd5b505191905056fea26469706673582212209317360118d1fea857794e2c2c0975d179def70482934438fa3aa8b36cfe12a864736f6c63430008190033", - "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fe5780638d1d47f11461013d578063de719b7614610158578063feaf968c14610167575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051600881526020015b60405180910390f35b6100b06101a6565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b0670d99a8cec7e2000081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f9190610292565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0670e27c49886e6000081565b61016f6101b6565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101b06101d7565b92915050565b5f805f805f806101c46101d7565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610231573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025591906102c7565b9050670d99a8cec7e20000811061028557670e27c49886e6000081116102785790565b50670e27c49886e6000090565b50670d99a8cec7e2000090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102d7575f80fd5b505191905056fea26469706673582212209317360118d1fea857794e2c2c0975d179def70482934438fa3aa8b36cfe12a864736f6c63430008190033", + "numDeployments": 3, + "solcInputHash": "18625204e1f090ab1a9c8ce54eea57c0", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_resilientOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LOWER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPPER_BOUND\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDT_TOKEN_ADDR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resilientOracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"StableUsdtPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/StableUsdtPriceFeed.sol\":\"StableUsdtPriceFeed\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/StableUsdtPriceFeed.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"../interfaces/OracleInterface.sol\\\";\\n\\n/**\\n * @title StableUsdtPriceFeed\\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\\n * and bounds the price to a certain range.\\n */\\ncontract StableUsdtPriceFeed {\\n ResilientOracleInterface public resilientOracle;\\n\\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\\n uint256 public constant UPPER_BOUND = 1020000000000000000; // 1.02 USD\\n uint256 public constant LOWER_BOUND = 980000000000000000; // 0.98 USD\\n\\n constructor(address _resilientOracle) {\\n require(_resilientOracle != address(0), \\\"Zero address provided\\\");\\n resilientOracle = ResilientOracleInterface(_resilientOracle);\\n }\\n\\n function latestAnswer() external view returns (int256 answer) {\\n // get price\\n uint256 price = getPrice();\\n // cast price to int256\\n answer = int256(price);\\n }\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\\n {\\n // get price\\n uint256 _answer = getPrice();\\n // mock timestamp to latest block timestamp\\n uint256 timestamp = block.timestamp;\\n // mock roundId to timestamp\\n roundId = uint80(timestamp);\\n return (roundId, int256(_answer), timestamp, timestamp, roundId);\\n }\\n\\n function decimals() external pure returns (uint8) {\\n return 18;\\n }\\n\\n function description() external pure returns (string memory) {\\n return \\\"Stabilized USDT Price Feed\\\";\\n }\\n\\n function version() external pure returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev Get the price from the Resilient Oracle, and bound it to the range\\n * @return price The price of USDT in 18 decimals\\n */\\n function getPrice() private view returns (uint256 price) {\\n // get USDT price (18 decimals)\\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\\n }\\n}\\n\",\"keccak256\":\"0x96c69dc61f78ad276dd7111371a61033be477122d8bfa26b5f410b1fbdff3ae7\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x6080604052348015600e575f80fd5b506040516103f33803806103f3833981016040819052602b9160a7565b6001600160a01b03811660845760405162461bcd60e51b815260206004820152601560248201527f5a65726f20616464726573732070726f76696465640000000000000000000000604482015260640160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560d2565b5f6020828403121560b6575f80fd5b81516001600160a01b038116811460cb575f80fd5b9392505050565b610314806100df5f395ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fe5780638d1d47f11461013d578063de719b7614610158578063feaf968c14610167575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051601281526020015b60405180910390f35b6100b06101a6565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b0670d99a8cec7e2000081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f9190610292565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0670e27c49886e6000081565b61016f6101b6565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101b06101d7565b92915050565b5f805f805f806101c46101d7565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610231573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025591906102c7565b9050670d99a8cec7e20000811061028557670e27c49886e6000081116102785790565b50670e27c49886e6000090565b50670d99a8cec7e2000090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102d7575f80fd5b505191905056fea26469706673582212203e450a15977976ec3a49a75bbb7030ba80e4627115738ccfd55efe1f36b16fa664736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c80636198e135116100635780636198e135146100ef5780637284e416146100fe5780638d1d47f11461013d578063de719b7614610158578063feaf968c14610167575f80fd5b8063313ce5671461009457806350d25bcd146100a857806354fd4d50146100be57806360de3604146100c5575b5f80fd5b604051601281526020015b60405180910390f35b6100b06101a6565b60405190815260200161009f565b60016100b0565b5f546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161009f565b6100b0670d99a8cec7e2000081565b604080518082018252601a81527f53746162696c697a6564205553445420507269636520466565640000000000006020820152905161009f9190610292565b6100d77355d398326f99059ff775485246999027b319795581565b6100b0670e27c49886e6000081565b61016f6101b6565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161009f565b5f806101b06101d7565b92915050565b5f805f805f806101c46101d7565b4297909650879550859450849350915050565b5f80546040516341976e0960e01b81527355d398326f99059ff775485246999027b319795560048201526001600160a01b03909116906341976e0990602401602060405180830381865afa158015610231573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025591906102c7565b9050670d99a8cec7e20000811061028557670e27c49886e6000081116102785790565b50670e27c49886e6000090565b50670d99a8cec7e2000090565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156102d7575f80fd5b505191905056fea26469706673582212203e450a15977976ec3a49a75bbb7030ba80e4627115738ccfd55efe1f36b16fa664736f6c63430008190033", "devdoc": { "details": "This contract is used to get the price of USDT from a Resilient Oracle and bounds the price to a certain range.", "kind": "dev", diff --git a/deployments/bscmainnet/solcInputs/18625204e1f090ab1a9c8ce54eea57c0.json b/deployments/bscmainnet/solcInputs/18625204e1f090ab1a9c8ce54eea57c0.json new file mode 100644 index 00000000..030cc6f0 --- /dev/null +++ b/deployments/bscmainnet/solcInputs/18625204e1f090ab1a9c8ce54eea57c0.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "contracts/oracles/StableUsdtPriceFeed.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ResilientOracleInterface } from \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title StableUsdtPriceFeed\n * @dev This contract is used to get the price of USDT from a Resilient Oracle\n * and bounds the price to a certain range.\n */\ncontract StableUsdtPriceFeed {\n ResilientOracleInterface public resilientOracle;\n\n address public constant USDT_TOKEN_ADDR = 0x55d398326f99059fF775485246999027B3197955;\n uint256 public constant UPPER_BOUND = 1020000000000000000; // 1.02 USD\n uint256 public constant LOWER_BOUND = 980000000000000000; // 0.98 USD\n\n constructor(address _resilientOracle) {\n require(_resilientOracle != address(0), \"Zero address provided\");\n resilientOracle = ResilientOracleInterface(_resilientOracle);\n }\n\n function latestAnswer() external view returns (int256 answer) {\n // get price\n uint256 price = getPrice();\n // cast price to int256\n answer = int256(price);\n }\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\n {\n // get price\n uint256 _answer = getPrice();\n // mock timestamp to latest block timestamp\n uint256 timestamp = block.timestamp;\n // mock roundId to timestamp\n roundId = uint80(timestamp);\n return (roundId, int256(_answer), timestamp, timestamp, roundId);\n }\n\n function decimals() external pure returns (uint8) {\n return 18;\n }\n\n function description() external pure returns (string memory) {\n return \"Stabilized USDT Price Feed\";\n }\n\n function version() external pure returns (uint256) {\n return 1;\n }\n\n /**\n * @dev Get the price from the Resilient Oracle, and bound it to the range\n * @return price The price of USDT in 18 decimals\n */\n function getPrice() private view returns (uint256 price) {\n // get USDT price (18 decimals)\n price = resilientOracle.getPrice(USDT_TOKEN_ADDR);\n price = price < LOWER_BOUND ? LOWER_BOUND : (price > UPPER_BOUND ? UPPER_BOUND : price);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} From 80dbbf777a21c81541ec955440422fed20e8361d Mon Sep 17 00:00:00 2001 From: Debugger022 <104391977+Debugger022@users.noreply.github.com> Date: Thu, 8 Jan 2026 16:30:53 +0000 Subject: [PATCH 6/6] feat: updating deployment files --- deployments/bscmainnet.json | 2 +- deployments/bscmainnet_addresses.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index a3cb4206..c565f483 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -14513,7 +14513,7 @@ ] }, "StableUsdtPriceFeed": { - "address": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", + "address": "0xf373A7a76De77f7A86ea65BE15577AEA8bE02A36", "abi": [ { "inputs": [ diff --git a/deployments/bscmainnet_addresses.json b/deployments/bscmainnet_addresses.json index bcafeab5..ca429cdb 100644 --- a/deployments/bscmainnet_addresses.json +++ b/deployments/bscmainnet_addresses.json @@ -48,7 +48,7 @@ "SolvBTC.BBN_OneJumpRedStoneOracle": "0x98B9bC5a1e7E439ebEB0BEdB7e9f6b24fEc1E8B4", "SolvBTC.BBN_OneJumpRedStoneOracle_Implementation": "0x98eD7290a3D52FA5639dd76C16ADE3074ba664dd", "SolvBTC.BBN_OneJumpRedStoneOracle_Proxy": "0x98B9bC5a1e7E439ebEB0BEdB7e9f6b24fEc1E8B4", - "StableUsdtPriceFeed": "0x854F10B9B7f10d58c493C4084c94c6CaDe38Fb44", + "StableUsdtPriceFeed": "0xf373A7a76De77f7A86ea65BE15577AEA8bE02A36", "StkBNBOracle": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6", "StkBNBOracle_Implementation": "0xA7C432c50D310c805c8342488921A108b585397F", "StkBNBOracle_Proxy": "0xdBAFD16c5eA8C29D1e94a5c26b31bFAC94331Ac6",