-
Notifications
You must be signed in to change notification settings - Fork 16
feat: Implemented Djed Tefnut smart contracts with ETH backing #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
cd77db8
4241283
8b32a4a
b012dac
bf0d013
4820fd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,85 @@ | ||||||
| // SPDX-License-Identifier: AEL | ||||||
| pragma solidity ^0.8.0; | ||||||
|
|
||||||
| /** | ||||||
| * @title DeploymentParametersTefnut | ||||||
| * @notice Configuration management for DjedTefnut deployment across different chains | ||||||
| * @dev Returns deployment parameters based on chain ID | ||||||
| */ | ||||||
| contract DeploymentParametersTefnut { | ||||||
|
|
||||||
| /// @notice Struct containing all DjedTefnut constructor parameters | ||||||
| struct Parameters { | ||||||
| address oracleAddress; // Oracle contract address (address(0) signals mock needed) | ||||||
| uint256 scalingFactor; // Scaling factor for decimal representation | ||||||
| address treasury; // Treasury address for fee collection | ||||||
| uint256 treasuryFee; // Fixed treasury fee (no decay) | ||||||
| uint256 fee; // Protocol fee | ||||||
| uint256 thresholdSupplySc; // Threshold supply for stable coins | ||||||
| uint256 rcMinPrice; // Minimum reserve coin price | ||||||
| uint256 rcInitialPrice; // Initial reserve coin price | ||||||
| uint256 txLimit; // Transaction limit | ||||||
| } | ||||||
|
|
||||||
| // Chain IDs | ||||||
| uint256 constant SEPOLIA_CHAIN_ID = 11155111; | ||||||
| uint256 constant ANVIL_CHAIN_ID = 31337; | ||||||
|
|
||||||
| // Known oracle addresses | ||||||
| address constant SEPOLIA_SHU_ORACLE_ADDRESS = address(0); // Placeholder - replace with actual address when deployed | ||||||
|
|
||||||
| // Known treasury addresses | ||||||
| address constant SEPOLIA_TREASURY = 0x0f5342B55ABCC0cC78bdB4868375bCA62B6c16eA; | ||||||
| address constant LOCAL_TREASURY = 0x078D888E40faAe0f32594342c85940AF3949E666; | ||||||
|
|
||||||
| /** | ||||||
| * @notice Get deployment parameters for a specific chain | ||||||
| * @param chainId The chain ID to get parameters for | ||||||
| * @return params The Parameters struct with all constructor arguments | ||||||
| */ | ||||||
| function getParams(uint256 chainId) public pure returns (Parameters memory params) { | ||||||
| if (chainId == SEPOLIA_CHAIN_ID) { | ||||||
| // Sepolia Testnet Configuration | ||||||
| params = Parameters({ | ||||||
| oracleAddress: SEPOLIA_SHU_ORACLE_ADDRESS, // Will be replaced with actual address | ||||||
| scalingFactor: 1e24, | ||||||
| treasury: SEPOLIA_TREASURY, | ||||||
| treasuryFee: 25e20, // 0.25% | ||||||
| fee: 15e21, // 1.5% | ||||||
| thresholdSupplySc: 5e11, // 500k SC | ||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| rcMinPrice: 1e18, // 1 ETH per RC | ||||||
| rcInitialPrice: 1e20, // 100 ETH per RC | ||||||
| txLimit: 1e10 // 10k SC | ||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| }); | ||||||
| } else { | ||||||
| // Local/Anvil Default Configuration | ||||||
| // oracleAddress = address(0) signals that a mock oracle should be deployed | ||||||
| params = Parameters({ | ||||||
| oracleAddress: address(0), // Signal to deploy mock | ||||||
| scalingFactor: 1e24, | ||||||
| treasury: LOCAL_TREASURY, | ||||||
| treasuryFee: 0, // 0% for testing | ||||||
| fee: 15e21, // 1.5% | ||||||
| thresholdSupplySc: 1e6, // 1M SC | ||||||
| rcMinPrice: 1e18, // 1 ETH per RC | ||||||
| rcInitialPrice: 1e20, // 100 ETH per RC | ||||||
| txLimit: 200e6 // 200 SC | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect comment: transaction limit is 200M SC, not 200 SC. The value Apply this diff to correct the comment: - txLimit: 200e6 // 200 SC
+ txLimit: 200e6 // 200M SC📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| }); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * @notice Get human-readable network name | ||||||
| * @param chainId The chain ID | ||||||
| * @return name The network name | ||||||
| */ | ||||||
| function getNetworkName(uint256 chainId) public pure returns (string memory name) { | ||||||
| if (chainId == SEPOLIA_CHAIN_ID) { | ||||||
| return "Ethereum Sepolia"; | ||||||
| } else if (chainId == ANVIL_CHAIN_ID) { | ||||||
| return "Anvil Local"; | ||||||
| } else { | ||||||
| return "Unknown Network"; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| // SPDX-License-Identifier: AEL | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import "forge-std/Script.sol"; | ||
| import "./DeploymentParametersTefnut.sol"; | ||
| import {DjedTefnut} from "../src/DjedTefnut.sol"; | ||
| import {MockShuOracleTefnut} from "../src/mock/MockShuOracleTefnut.sol"; | ||
|
|
||
| /** | ||
| * @title DeployDjedTefnut | ||
| * @notice Deployment script for DjedTefnut contract | ||
| * @dev Automatically deploys mock oracle for local/test chains | ||
| * | ||
| * Usage: | ||
| * Local (Anvil): forge script scripts/deployDjedTefnutContract.s.sol --broadcast --rpc-url http://127.0.0.1:8545 | ||
| * Sepolia: forge script scripts/deployDjedTefnutContract.s.sol --broadcast --rpc-url $SEPOLIA_RPC_URL | ||
| */ | ||
| contract DeployDjedTefnut is Script, DeploymentParametersTefnut { | ||
|
|
||
| // Default oracle exchange rate: 1 USD = 0.5 ETH (in weis per whole SC) | ||
| uint256 constant DEFAULT_ORACLE_PRICE = 5e17; | ||
|
|
||
| // Initial balance to seed the contract | ||
| uint256 constant INITIAL_BALANCE = 1e18; // 1 ETH | ||
|
|
||
| function run() external { | ||
| // Get deployment parameters based on current chain | ||
| Parameters memory params = getParams(block.chainid); | ||
|
|
||
| console.log("==========================================="); | ||
| console.log("Deploying DjedTefnut"); | ||
| console.log("Network:", getNetworkName(block.chainid)); | ||
| console.log("Chain ID:", block.chainid); | ||
| console.log("==========================================="); | ||
|
|
||
| // Start broadcasting transactions | ||
| uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
| vm.startBroadcast(deployerPrivateKey); | ||
|
|
||
| // Dynamic Mocking: Deploy mock oracle if oracleAddress is address(0) | ||
| if (params.oracleAddress == address(0)) { | ||
| console.log(""); | ||
| console.log("Oracle address is zero - deploying MockShuOracleTefnut..."); | ||
|
|
||
| MockShuOracleTefnut mockOracle = new MockShuOracleTefnut(DEFAULT_ORACLE_PRICE); | ||
| params.oracleAddress = address(mockOracle); | ||
|
|
||
| console.log("MockShuOracleTefnut deployed at:", address(mockOracle)); | ||
| console.log("Initial oracle price:", DEFAULT_ORACLE_PRICE); | ||
| } | ||
|
|
||
| // Log deployment parameters | ||
| console.log(""); | ||
| console.log("Deployment Parameters:"); | ||
| console.log(" Oracle Address:", params.oracleAddress); | ||
| console.log(" Scaling Factor:", params.scalingFactor); | ||
| console.log(" Treasury:", params.treasury); | ||
| console.log(" Treasury Fee:", params.treasuryFee); | ||
| console.log(" Fee:", params.fee); | ||
| console.log(" Threshold Supply SC:", params.thresholdSupplySc); | ||
| console.log(" RC Min Price:", params.rcMinPrice); | ||
| console.log(" RC Initial Price:", params.rcInitialPrice); | ||
| console.log(" TX Limit:", params.txLimit); | ||
|
|
||
| // Deploy DjedTefnut with the (potentially updated) parameters | ||
| DjedTefnut djedTefnut = new DjedTefnut{value: INITIAL_BALANCE}( | ||
| params.oracleAddress, | ||
| params.scalingFactor, | ||
| params.treasury, | ||
| params.treasuryFee, | ||
| params.fee, | ||
| params.thresholdSupplySc, | ||
| params.rcMinPrice, | ||
| params.rcInitialPrice, | ||
| params.txLimit | ||
| ); | ||
|
|
||
| console.log(""); | ||
| console.log("==========================================="); | ||
| console.log("DjedTefnut deployed at:", address(djedTefnut)); | ||
| console.log("StableCoin deployed at:", address(djedTefnut.stableCoin())); | ||
| console.log("ReserveCoin deployed at:", address(djedTefnut.reserveCoin())); | ||
| console.log("Initial Reserve:", address(djedTefnut).balance); | ||
| console.log("==========================================="); | ||
|
|
||
| vm.stopBroadcast(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,218 @@ | ||
| // SPDX-License-Identifier: AEL | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; | ||
| import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; | ||
| import {Coin} from "./Coin.sol"; | ||
| import {IOracleShu} from "./IOracleShu.sol"; | ||
|
|
||
|
Comment on lines
+1
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SPDX identifier If 🤖 Prompt for AI Agents
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isnt this incorrect? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query: 💡 Result: Do you mean a specific license abbreviated “AEL”? If so, what does AEL stand for (full license name or a link)? I can then look up the correct SPDX identifier. 🌐 Web query: 💡 Result: The official SPDX license identifiers are published on the SPDX License List page and in the SPDX license-list-data repository (machine-readable JSON/XML). Use the licenses page for the human-readable table and the GitHub repo (licenses.json / exceptions.json) for authoritative identifiers you can consume programmatically. Current references:
If you want the full JSON file of identifiers, download licenses.json from the license-list-data repo. [2] Sources 🏁 Script executed: Length of output: 0 @negimox, I've checked the official SPDX license list (version 3.27.0), and "AEL" is not a recognized standard SPDX license identifier. So CodeRabbit's warning is technically accurate from a standards perspective. However, if "AEL" is a custom or proprietary license identifier specific to your project (such as "All Emcompassing License" or similar), then using it may be intentional. Could you clarify:
If it's a custom identifier and intentional, you can safely ignore the warning. If you meant to use a standard SPDX identifier, I can help you find the appropriate one. Alternatively, if the code is proprietary/closed-source, you might want to use |
||
| contract DjedTefnut is ReentrancyGuard { | ||
| IOracleShu public oracle; | ||
| Coin public stableCoin; | ||
| Coin public reserveCoin; | ||
|
|
||
| // Treasury Parameters: | ||
| address public immutable TREASURY; // address of the treasury | ||
| uint256 public immutable TREASURY_FEE; // fixed treasury fee (no decay) | ||
|
|
||
| // Djed Parameters: | ||
| uint256 public immutable FEE; | ||
| uint256 public immutable THRESHOLD_SUPPLY_SC; | ||
| uint256 public immutable RC_MIN_PRICE; | ||
| uint256 public immutable RC_INITIAL_PRICE; | ||
| uint256 public immutable TX_LIMIT; | ||
|
|
||
| // Scaling factors: | ||
| uint256 public immutable SCALING_FACTOR; // used to represent a decimal number `d` as the uint number `d * SCALING_FACTOR` | ||
| uint256 public immutable SC_DECIMAL_SCALING_FACTOR; | ||
| uint256 public immutable RC_DECIMAL_SCALING_FACTOR; | ||
|
|
||
| event BoughtStableCoins(address indexed buyer, address indexed receiver, uint256 amountSc, uint256 amountBc); | ||
| event SoldStableCoins(address indexed seller, address indexed receiver, uint256 amountSc, uint256 amountBc); | ||
| event BoughtReserveCoins(address indexed buyer, address indexed receiver, uint256 amountRc, uint256 amountBc); | ||
| event SoldReserveCoins(address indexed seller, address indexed receiver, uint256 amountRc, uint256 amountBc); | ||
|
|
||
| constructor( | ||
| address oracleAddress, | ||
| uint256 scalingFactor, | ||
| address treasury, | ||
| uint256 treasuryFee, | ||
| uint256 fee, | ||
| uint256 thresholdSupplySc, | ||
| uint256 rcMinPrice, | ||
| uint256 rcInitialPrice, | ||
| uint256 txLimit | ||
| ) payable { | ||
| // Constructor validation | ||
| require(oracleAddress != address(0), "Invalid oracle address"); | ||
| require(treasury != address(0), "Invalid treasury address"); | ||
| require(scalingFactor > 0, "Scaling factor must be > 0"); | ||
| require(fee + treasuryFee <= scalingFactor, "Total fees exceed 100%"); | ||
| require(rcInitialPrice >= rcMinPrice, "Initial price < min price"); | ||
| require(thresholdSupplySc > 0, "Threshold supply must be > 0"); | ||
| require(txLimit > 0, "TX limit must be > 0"); | ||
|
|
||
| stableCoin = new Coin("StableCoin", "SC"); | ||
| reserveCoin = new Coin("ReserveCoin", "RC"); | ||
| SC_DECIMAL_SCALING_FACTOR = 10 ** stableCoin.decimals(); | ||
| RC_DECIMAL_SCALING_FACTOR = 10 ** reserveCoin.decimals(); | ||
| SCALING_FACTOR = scalingFactor; | ||
|
|
||
| TREASURY = treasury; | ||
| TREASURY_FEE = treasuryFee; | ||
|
|
||
| FEE = fee; | ||
| THRESHOLD_SUPPLY_SC = thresholdSupplySc; | ||
| RC_MIN_PRICE = rcMinPrice; | ||
| RC_INITIAL_PRICE = rcInitialPrice; | ||
| TX_LIMIT = txLimit; | ||
|
|
||
| oracle = IOracleShu(oracleAddress); | ||
| oracle.acceptTermsOfService(); | ||
| } | ||
|
|
||
| // Reserve, Liabilities, Equity (in weis) and Reserve Ratio | ||
| function R(uint256 currentPaymentAmount) public view returns (uint256) { | ||
| return address(this).balance - currentPaymentAmount; | ||
| } | ||
|
|
||
| function L(uint256 _scPrice) internal view returns (uint256) { | ||
| return (stableCoin.totalSupply() * _scPrice) / SC_DECIMAL_SCALING_FACTOR; | ||
| } | ||
|
|
||
| function L() external view returns (uint256) { | ||
| return L(scMaxPrice(0)); | ||
| } | ||
|
|
||
| function E(uint256 _scPrice, uint256 currentPaymentAmount) internal view returns (uint256) { | ||
| return R(currentPaymentAmount) - L(_scPrice); | ||
| } | ||
|
|
||
| function E(uint256 currentPaymentAmount) external view returns (uint256) { | ||
| return E(scMaxPrice(currentPaymentAmount), currentPaymentAmount); | ||
| } | ||
|
|
||
| // Ratio functions kept for informational purposes only (no longer restrict transactions) | ||
| function ratio() external view returns (uint256) { | ||
| uint256 liabilities = L(scMaxPrice(0)); | ||
| if (liabilities == 0) return type(uint256).max; | ||
| return SCALING_FACTOR * R(0) / liabilities; | ||
| } | ||
|
|
||
| // # Public Trading Functions: | ||
| // scMaxPrice | ||
| function buyStableCoins(address receiver, uint256 feeUi, address ui) external payable nonReentrant { | ||
| oracle.updateOracleValues(); | ||
| uint256 scP = scMaxPrice(msg.value); | ||
| uint256 amountBc = deductFees(msg.value, feeUi, ui); | ||
| uint256 amountSc = (amountBc * SC_DECIMAL_SCALING_FACTOR) / scP; | ||
| require(amountSc <= TX_LIMIT || stableCoin.totalSupply() < THRESHOLD_SUPPLY_SC, "buySC: tx limit exceeded"); | ||
| require(amountSc > 0, "buySC: receiving zero SCs"); | ||
| stableCoin.mint(receiver, amountSc); | ||
| // Reserve ratio check removed in Tefnut | ||
| emit BoughtStableCoins(msg.sender, receiver, amountSc, amountBc); | ||
| } | ||
|
|
||
| function sellStableCoins(uint256 amountSc, address receiver, uint256 feeUi, address ui) external nonReentrant { | ||
| oracle.updateOracleValues(); | ||
| require(stableCoin.balanceOf(msg.sender) >= amountSc, "sellSC: insufficient SC balance"); | ||
| require(amountSc <= TX_LIMIT || stableCoin.totalSupply() < THRESHOLD_SUPPLY_SC, "sellSC: tx limit exceeded"); | ||
| uint256 scP = scMinPrice(0); | ||
| uint256 value = (amountSc * scP) / SC_DECIMAL_SCALING_FACTOR; | ||
| uint256 amountBc = deductFees(value, feeUi, ui); | ||
| require(amountBc > 0, "sellSC: receiving zero BCs"); | ||
| stableCoin.burn(msg.sender, amountSc); | ||
| transferEth(receiver, amountBc); | ||
| emit SoldStableCoins(msg.sender, receiver, amountSc, amountBc); | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| function buyReserveCoins(address receiver, uint256 feeUi, address ui) external payable nonReentrant { | ||
| oracle.updateOracleValues(); | ||
| uint256 scP = scMinPrice(msg.value); | ||
| uint256 rcBp = rcBuyingPrice(scP, msg.value); | ||
| uint256 amountBc = deductFees(msg.value, feeUi, ui); | ||
| require(amountBc <= (TX_LIMIT * scP) / SC_DECIMAL_SCALING_FACTOR || stableCoin.totalSupply() < THRESHOLD_SUPPLY_SC, "buyRC: tx limit exceeded"); | ||
| uint256 amountRc = (amountBc * RC_DECIMAL_SCALING_FACTOR) / rcBp; | ||
| require(amountRc > 0, "buyRC: receiving zero RCs"); | ||
| reserveCoin.mint(receiver, amountRc); | ||
| // Reserve ratio check removed in Tefnut | ||
| emit BoughtReserveCoins(msg.sender, receiver, amountRc, amountBc); | ||
| } | ||
|
|
||
| function sellReserveCoins(uint256 amountRc, address receiver, uint256 feeUi, address ui) external nonReentrant { | ||
| oracle.updateOracleValues(); | ||
| require(reserveCoin.balanceOf(msg.sender) >= amountRc, "sellRC: insufficient RC balance"); | ||
| uint256 scP = scMaxPrice(0); | ||
| uint256 value = (amountRc * rcTargetPrice(scP, 0)) / RC_DECIMAL_SCALING_FACTOR; | ||
| require(value <= (TX_LIMIT * scP) / SC_DECIMAL_SCALING_FACTOR || stableCoin.totalSupply() < THRESHOLD_SUPPLY_SC, "sellRC: tx limit exceeded"); | ||
| uint256 amountBc = deductFees(value, feeUi, ui); | ||
| require(amountBc > 0, "sellRC: receiving zero BCs"); | ||
| reserveCoin.burn(msg.sender, amountRc); | ||
| transferEth(receiver, amountBc); | ||
| // Reserve ratio check removed in Tefnut | ||
| emit SoldReserveCoins(msg.sender, receiver, amountRc, amountBc); | ||
| } | ||
|
|
||
| // sellBothCoins function removed in Tefnut | ||
|
|
||
| // # Auxiliary Functions | ||
|
|
||
| function deductFees(uint256 value, uint256 feeUi, address ui) internal returns (uint256) { | ||
| require(ui != address(0), "Invalid UI address"); | ||
| require(feeUi + FEE + TREASURY_FEE <= SCALING_FACTOR, "Total fees exceed 100%"); | ||
| uint256 f = (value * FEE) / SCALING_FACTOR; | ||
| uint256 fUi = (value * feeUi) / SCALING_FACTOR; | ||
| uint256 fT = (value * TREASURY_FEE) / SCALING_FACTOR; // Fixed treasury fee (no decay) | ||
| transferEth(TREASURY, fT); | ||
| transferEth(ui, fUi); | ||
| // transferEth(address(this), f); // this happens implicitly, and thus `f` is effectively transferred to the reserve. | ||
| return value - f - fUi - fT; // amountBc | ||
| } | ||
|
|
||
| // isRatioAboveMin and isRatioBelowMax functions removed in Tefnut | ||
|
|
||
| // # Price Functions: return the price in weis for 1 whole coin. | ||
|
|
||
| function scPrice(uint256 currentPaymentAmount, uint256 scTargetPrice) private view returns (uint256) { | ||
| uint256 supplySc = stableCoin.totalSupply(); | ||
| return supplySc == 0 | ||
| ? scTargetPrice | ||
| : Math.min(scTargetPrice, (R(currentPaymentAmount) * SC_DECIMAL_SCALING_FACTOR) / supplySc); | ||
| } | ||
|
|
||
| function scMaxPrice(uint256 currentPaymentAmount) public view returns (uint256) { | ||
| (uint256 scTargetPrice,) = oracle.readMaxPrice(); | ||
| return scPrice(currentPaymentAmount, scTargetPrice); | ||
| } | ||
|
|
||
| function scMinPrice(uint256 currentPaymentAmount) public view returns (uint256) { | ||
| (uint256 scTargetPrice,) = oracle.readMinPrice(); | ||
| return scPrice(currentPaymentAmount, scTargetPrice); | ||
| } | ||
|
|
||
| function rcTargetPrice(uint256 currentPaymentAmount) external view returns (uint256) { | ||
| return rcTargetPrice(scMaxPrice(currentPaymentAmount), currentPaymentAmount); | ||
| } | ||
|
|
||
| function rcTargetPrice(uint256 _scPrice, uint256 currentPaymentAmount) internal view returns (uint256) { | ||
| uint256 supplyRc = reserveCoin.totalSupply(); | ||
| require(supplyRc != 0, "RC supply is zero"); | ||
| require(R(currentPaymentAmount) >= L(_scPrice), "Under-collateralized: reserve < liability"); | ||
| return (E(_scPrice, currentPaymentAmount) * RC_DECIMAL_SCALING_FACTOR) / supplyRc; | ||
| } | ||
|
|
||
| function rcBuyingPrice(uint256 currentPaymentAmount) external view returns (uint256) { | ||
| return rcBuyingPrice(scMaxPrice(currentPaymentAmount), currentPaymentAmount); | ||
| } | ||
|
|
||
| function rcBuyingPrice(uint256 _scPrice, uint256 currentPaymentAmount) internal view returns (uint256) { | ||
| return reserveCoin.totalSupply() == 0 | ||
| ? RC_INITIAL_PRICE | ||
| : Math.max(rcTargetPrice(_scPrice, currentPaymentAmount), RC_MIN_PRICE); | ||
| } | ||
|
|
||
| function transferEth(address receiver, uint256 amount) internal { | ||
| (bool success,) = payable(receiver).call{value: amount}(""); | ||
| require(success, "Transfer failed."); | ||
| } | ||
negimox marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sepolia will deploy with mock oracle instead of real oracle.
The
SEPOLIA_SHU_ORACLE_ADDRESSis set toaddress(0)as a placeholder. However, the deployment script interpretsaddress(0)as a signal to deployMockShuOracleTefnut. This means Sepolia deployments will use a mock oracle rather than a production oracle, which may not be intended for testnet deployments.Update the placeholder comment to clarify this behavior, or replace with the actual Sepolia oracle address when available:
📝 Committable suggestion
🤖 Prompt for AI Agents