contract StablePriceOracle is Ownable, PriceOracle {
    using SafeMath for *;
    using StringUtils for *;

    // Oracle address
    DSValue usdOracle;

    // Rent in attodollars (1e-18) per second
    uint[] public rentPrices;

    event OracleChanged(address oracle);
    event RentPriceChanged(uint[] prices);

    constructor(DSValue _usdOracle, uint[] memory _rentPrices) public {
        setOracle(_usdOracle);
        setPrices(_rentPrices);
    }

    /**
     * @dev Sets the price oracle address
     * @param _usdOracle The address of the price oracle to use.
     */
    function setOracle(DSValue _usdOracle) public onlyOwner {
        usdOracle = _usdOracle;
        emit OracleChanged(address(_usdOracle));
    }

    /**
     * @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.
     */
    function setPrices(uint[] memory _rentPrices) public onlyOwner {
        rentPrices = _rentPrices;
        emit RentPriceChanged(_rentPrices);
    }

    /**
     * @dev Returns the price to register or renew a name.
     * @param name The name being registered or renewed.
     * @param duration How long the name is being registered or extended for, in seconds.
     * @return The price of this renewal or registration, in wei.
     */
    function price(string calldata name, uint /*expires*/, uint duration) view external returns(uint) {
        uint len = name.strlen();
        if(len > rentPrices.length) {
            len = rentPrices.length;
        }
        require(len > 0);
        uint priceUSD = rentPrices[len - 1].mul(duration);

        // Price of one ether in attodollars
        uint ethPrice = uint(usdOracle.read());

        // priceUSD and ethPrice are both fixed-point values with 18dp, so we
        // multiply the numerator by 1e18 before dividing.
        return priceUSD.mul(1e18).div(ethPrice);
    }
}
// StablePriceOracle sets a price in USD, based on an oracle.
function price(string calldata name, uint /*expires*/, uint duration) view external returns(uint) {
        uint len = name.strlen();
        if(len > rentPrices.length) {
            len = rentPrices.length;
        }
        require(len > 0);
        uint priceUSD = rentPrices[len - 1].mul(duration);

        // Price of one ether in attodollars
        uint ethPrice = uint(usdOracle.read());

        // priceUSD and ethPrice are both fixed-point values with 18dp, so we
        // multiply the numerator by 1e18 before dividing.
        return priceUSD.mul(1e18).div(ethPrice);
    }
/**
 * @dev Returns the price to register or renew a name.
 * @param name The name being registered or renewed.
 * @param duration How long the name is being registered or extended for, in seconds.
 * @return The price of this renewal or registration, in wei.
 */