pragma solidity >=0.8.4; import "./PriceOracle.sol"; import "./SafeMath.sol"; import "./StringUtils.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; // NativePrice sets a price in native chain currency (e.g. ETH). contract NativePriceOracle is Ownable, PriceOracle { using SafeMath for *; using StringUtils for *; // Rent in base price units by length. Element 0 is for 1-length names, and so on. uint[] public rentPrices; event RentPriceChanged(uint[] prices); bytes4 constant private INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)")); bytes4 constant private ORACLE_ID = bytes4(keccak256("price(string,uint256,uint256)") ^ keccak256("premium(string,uint256,uint256)")); constructor(uint[] memory _rentPrices) public { setPrices(_rentPrices); } function price(string calldata name, uint expires, uint duration) external view override returns(uint) { uint len = name.strlen(); if(len > rentPrices.length) { len = rentPrices.length; } require(len > 0); uint basePrice = rentPrices[len - 1].mul(duration); basePrice = basePrice.add(_premium(name, expires, duration)); return basePrice; } /** * @dev Sets rent prices. * @param _rentPrices The price array. Each element corresponds to a specific * name length; names longer than the length of the array * default to the price of the last element. Values are * in base price units per second, equal to one wei (1e-18 * ETH) each. */ function setPrices(uint[] memory _rentPrices) public onlyOwner { rentPrices = _rentPrices; emit RentPriceChanged(_rentPrices); } /** * @dev Returns the pricing premium in internal base units. */ function _premium(string memory name, uint expires, uint duration) virtual internal view returns(uint) { return 0; } function supportsInterface(bytes4 interfaceID) public view virtual returns (bool) { return interfaceID == INTERFACE_META_ID || interfaceID == ORACLE_ID; } }