Address Contract Verified
Address
0xCF7fe2e614f568989869F4AADe060F4EB8a105BE
Balance
0 ETH
Nonce
1
Code Size
4924 bytes
Creator
0x0904Dac3...9859 at tx 0xc2ed7f1b...ceffdd
Indexed Transactions
0
Contract Bytecode
4924 bytes
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c806379cf92d311610076578063a34e35961161005b578063a34e35961461018e578063c8a4271f146101a1578063f2fde38b146101c857600080fd5b806379cf92d31461013c5780638da5cb5b1461014f57600080fd5b806350e9a715116100a757806350e9a7151461010c57806359e1777c1461011f578063715018a61461013257600080fd5b806301ffc9a7146100c357806306d5d0b6146100eb575b600080fd5b6100d66100d136600461107b565b6101db565b60405190151581526020015b60405180910390f35b6100fe6100f936600461114d565b6101ec565b6040519081526020016100e2565b6100fe61011a3660046110d3565b61020d565b6100fe61012d366004611165565b610335565b61013a6103d0565b005b61013a61014a366004610f9d565b610462565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e2565b6100fe61019c3660046110d3565b610531565b6101697f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b841981565b61013a6101d6366004610f69565b610589565b60006101e6826106b9565b92915050565b600181815481106101fc57600080fd5b600091825260209091200154905081565b60008061024f86868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061075192505050565b60015490915081111561026157506001545b6000811161026e57600080fd5b60006102d08460016102808186611258565b815481106102b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015461097f90919063ffffffff16565b905061031f61031888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92508991506109b89050565b8290610a7b565b905061032a81610a97565b979650505050505050565b6000806201518061034e670de0b6b3a76400008561121b565b61035891906111e2565b9050600061036e670de0b6b3a7640000836111e2565b905084811c6000610387670de0b6b3a76400008461121b565b6103919085611258565b90506000670de0b6b3a76400006103ab836201000061121b565b6103b591906111e2565b905060006103c38285610b52565b9998505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610456576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6104606000610e72565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161044d565b80516104f6906001906020840190610f09565b507f73422d94aedd596c2d4d39f27a01033adc390a9054efaf259afefd95ef7331df816040516105269190611186565b60405180910390a150565b60008061057f61057a87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508992508891506109b89050565b610a97565b9695505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461060a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161044d565b73ffffffffffffffffffffffffffffffffffffffff81166106ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161044d565b6106b681610e72565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806101e657507fffffffff0000000000000000000000000000000000000000000000000000000082167ff3a79283000000000000000000000000000000000000000000000000000000001492915050565b8051600090819081905b8082101561097657600085838151811061079e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f8000000000000000000000000000000000000000000000000000000000000000811015610801576107fa6001846111ca565b9250610963565b7fe0000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082161015610856576107fa6002846111ca565b7ff0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156108ab576107fa6003846111ca565b7ff8000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082161015610900576107fa6004846111ca565b7ffc000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082161015610955576107fa6005846111ca565b6109606006846111ca565b92505b508261096e8161126f565b93505061075b565b50909392505050565b60008261098e575060006101e6565b600061099a838561121b565b9050826109a785836111e2565b146109b157600080fd5b9392505050565b60006109c76276a700846111ca565b9250428311156109d9575060006109b1565b60006109e58442611258565b90506000610a137f00000000000000000000000000000000000000000052b7d2dcc80cd2e400000083610335565b90507f00000000000000000000000000000000000000000000000295be96e6406697208110610a6f57610a667f00000000000000000000000000000000000000000000000295be96e64066972082611258565b925050506109b1565b50600095945050505050565b600080610a8883856111ca565b9050838110156109b157600080fd5b6000807f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b841973ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0057600080fd5b505afa158015610b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3891906110bb565b90506109b181610b4c856305f5e10061097f565b90610ee7565b60006001831615610b8557670de0b6b3a7640000610b78670de0ad151d0941808461121b565b610b8291906111e2565b91505b6002831615610bb657670de0b6b3a7640000610ba9670de0a376995968008461121b565b610bb391906111e2565b91505b6004831615610be757670de0b6b3a7640000610bda670de09039a5fa51008461121b565b610be491906111e2565b91505b6008831615610c1857670de0b6b3a7640000610c0b670de069c00f3e12008461121b565b610c1591906111e2565b91505b6010831615610c4957670de0b6b3a7640000610c3c670de01cce21c944008461121b565b610c4691906111e2565b91505b6020831615610c7a57670de0b6b3a7640000610c6d670ddf82ef46ce10008461121b565b610c7791906111e2565b91505b6040831615610cab57670de0b6b3a7640000610c9e670dde4f458f8e8d808461121b565b610ca891906111e2565b91505b6080831615610cdc57670de0b6b3a7640000610ccf670ddbe84213d5f0808461121b565b610cd991906111e2565b91505b610100831615610d0e57670de0b6b3a7640000610d01670dd71b7aa6df5b808461121b565b610d0b91906111e2565b91505b610200831615610d4057670de0b6b3a7640000610d33670dcd86e7f28cde008461121b565b610d3d91906111e2565b91505b610400831615610d7257670de0b6b3a7640000610d65670dba71a3084ad6808461121b565b610d6f91906111e2565b91505b610800831615610da457670de0b6b3a7640000610d97670d94961b13dbde808461121b565b610da191906111e2565b91505b611000831615610dd657670de0b6b3a7640000610dc9670d4a171c35c983808461121b565b610dd391906111e2565b91505b612000831615610e0857670de0b6b3a7640000610dfb670cb9da519ccfb7008461121b565b610e0591906111e2565b91505b614000831615610e3a57670de0b6b3a7640000610e2d670bab76d59c18d6808461121b565b610e3791906111e2565b91505b618000831615610e6c57670de0b6b3a7640000610e5f6709d025defee4df808461121b565b610e6991906111e2565b91505b50919050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808211610ef557600080fd5b6000610f0183856111e2565b949350505050565b828054828255906000526020600020908101928215610f44579160200282015b82811115610f44578251825591602001919060010190610f29565b50610f50929150610f54565b5090565b5b80821115610f505760008155600101610f55565b600060208284031215610f7a578081fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146109b1578182fd5b60006020808385031215610faf578182fd5b823567ffffffffffffffff80821115610fc6578384fd5b818501915085601f830112610fd9578384fd5b813581811115610feb57610feb6112d7565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561102e5761102e6112d7565b604052828152858101935084860182860187018a101561104c578788fd5b8795505b8386101561106e578035855260019590950194938601938601611050565b5098975050505050505050565b60006020828403121561108c578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146109b1578182fd5b6000602082840312156110cc578081fd5b5051919050565b600080600080606085870312156110e8578283fd5b843567ffffffffffffffff808211156110ff578485fd5b818701915087601f830112611112578485fd5b813581811115611120578586fd5b886020828501011115611131578586fd5b6020928301999098509187013596604001359550909350505050565b60006020828403121561115e578081fd5b5035919050565b60008060408385031215611177578182fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156111be578351835292840192918401916001016111a2565b50909695505050505050565b600082198211156111dd576111dd6112a8565b500190565b600082611216577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611253576112536112a8565b500290565b60008282101561126a5761126a6112a8565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156112a1576112a16112a8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220765692640890cdacba63b8b569b2cfab46efc7762637da7215a9bde8f02b390864736f6c63430008040033
Verified Source Code Full Match
Compiler: v0.8.4+commit.c7e474f2
EVM: istanbul
Optimization: Yes (10000 runs)
StringUtils.sol 32 lines
pragma solidity >=0.8.4;
library StringUtils {
/**
* @dev Returns the length of a given string
*
* @param s The string to measure the length of
* @return The length of the input string
*/
function strlen(string memory s) internal pure returns (uint) {
uint len;
uint i = 0;
uint bytelength = bytes(s).length;
for(len = 0; i < bytelength; len++) {
bytes1 b = bytes(s)[i];
if(b < 0x80) {
i += 1;
} else if (b < 0xE0) {
i += 2;
} else if (b < 0xF0) {
i += 3;
} else if (b < 0xF8) {
i += 4;
} else if (b < 0xFC) {
i += 5;
} else {
i += 6;
}
}
return len;
}
}
Ownable.sol 76 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
ExponentialPremiumPriceOracle.sol 144 lines
pragma solidity >=0.8.4;
import "./SafeMath.sol";
import "./StablePriceOracle.sol";
contract ExponentialPremiumPriceOracle is StablePriceOracle {
uint256 constant GRACE_PERIOD = 90 days;
uint256 immutable startPremium;
uint256 immutable endValue;
constructor(
AggregatorInterface _usdOracle,
uint256[] memory _rentPrices,
uint256 _startPremium,
uint256 totalDays
) StablePriceOracle(_usdOracle, _rentPrices) {
startPremium = _startPremium;
endValue = _startPremium >> totalDays;
}
uint256 constant PRECISION = 1e18;
uint256 constant bit1 = 999989423469314432; // 0.5 ^ 1/65536 * (10 ** 18)
uint256 constant bit2 = 999978847050491904; // 0.5 ^ 2/65536 * (10 ** 18)
uint256 constant bit3 = 999957694548431104;
uint256 constant bit4 = 999915390886613504;
uint256 constant bit5 = 999830788931929088;
uint256 constant bit6 = 999661606496243712;
uint256 constant bit7 = 999323327502650752;
uint256 constant bit8 = 998647112890970240;
uint256 constant bit9 = 997296056085470080;
uint256 constant bit10 = 994599423483633152;
uint256 constant bit11 = 989228013193975424;
uint256 constant bit12 = 978572062087700096;
uint256 constant bit13 = 957603280698573696;
uint256 constant bit14 = 917004043204671232;
uint256 constant bit15 = 840896415253714560;
uint256 constant bit16 = 707106781186547584;
/**
* @dev Returns the pricing premium in internal base units.
*/
function _premium(
string memory,
uint256 expires,
uint256
) internal view override returns (uint256) {
expires = expires + GRACE_PERIOD;
if (expires > block.timestamp) {
return 0;
}
uint256 elapsed = block.timestamp - expires;
uint256 premium = decayedPremium(startPremium, elapsed);
if (premium >= endValue) {
return premium - endValue;
}
return 0;
}
/**
* @dev Returns the premium price at current time elapsed
* @param startPremium starting price
* @param elapsed time past since expiry
*/
function decayedPremium(uint256 startPremium, uint256 elapsed)
public
pure
returns (uint256)
{
uint256 daysPast = (elapsed * PRECISION) / 1 days;
uint256 intDays = daysPast / PRECISION;
uint256 premium = startPremium >> intDays;
uint256 partDay = (daysPast - intDays * PRECISION);
uint256 fraction = (partDay * (2**16)) / PRECISION;
uint256 totalPremium = addFractionalPremium(fraction, premium);
return totalPremium;
}
function addFractionalPremium(uint256 fraction, uint256 premium)
internal
pure
returns (uint256)
{
if (fraction & (1 << 0) != 0) {
premium = (premium * bit1) / PRECISION;
}
if (fraction & (1 << 1) != 0) {
premium = (premium * bit2) / PRECISION;
}
if (fraction & (1 << 2) != 0) {
premium = (premium * bit3) / PRECISION;
}
if (fraction & (1 << 3) != 0) {
premium = (premium * bit4) / PRECISION;
}
if (fraction & (1 << 4) != 0) {
premium = (premium * bit5) / PRECISION;
}
if (fraction & (1 << 5) != 0) {
premium = (premium * bit6) / PRECISION;
}
if (fraction & (1 << 6) != 0) {
premium = (premium * bit7) / PRECISION;
}
if (fraction & (1 << 7) != 0) {
premium = (premium * bit8) / PRECISION;
}
if (fraction & (1 << 8) != 0) {
premium = (premium * bit9) / PRECISION;
}
if (fraction & (1 << 9) != 0) {
premium = (premium * bit10) / PRECISION;
}
if (fraction & (1 << 10) != 0) {
premium = (premium * bit11) / PRECISION;
}
if (fraction & (1 << 11) != 0) {
premium = (premium * bit12) / PRECISION;
}
if (fraction & (1 << 12) != 0) {
premium = (premium * bit13) / PRECISION;
}
if (fraction & (1 << 13) != 0) {
premium = (premium * bit14) / PRECISION;
}
if (fraction & (1 << 14) != 0) {
premium = (premium * bit15) / PRECISION;
}
if (fraction & (1 << 15) != 0) {
premium = (premium * bit16) / PRECISION;
}
return premium;
}
function supportsInterface(bytes4 interfaceID)
public
view
virtual
override
returns (bool)
{
return super.supportsInterface(interfaceID);
}
}
PriceOracle.sol 12 lines
pragma solidity >=0.8.4;
interface PriceOracle {
/**
* @dev Returns the price to register or renew a name.
* @param name The name being registered or renewed.
* @param expires When the name presently expires (0 if this is a new registration).
* @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) external view returns(uint);
}
SafeMath.sol 65 lines
pragma solidity >=0.8.4;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
StablePriceOracle.sol 113 lines
pragma solidity >=0.8.4;
import "./PriceOracle.sol";
import "./SafeMath.sol";
import "./StringUtils.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
interface AggregatorInterface {
function latestAnswer() external view returns (int256);
}
// StablePriceOracle sets a price in USD, based on an oracle.
contract StablePriceOracle 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.
uint256[] public rentPrices;
// Oracle address
AggregatorInterface public immutable usdOracle;
event OracleChanged(address oracle);
event RentPriceChanged(uint256[] prices);
bytes4 private constant INTERFACE_META_ID =
bytes4(keccak256("supportsInterface(bytes4)"));
bytes4 private constant ORACLE_ID =
bytes4(
keccak256("price(string,uint256,uint256)") ^
keccak256("premium(string,uint256,uint256)")
);
constructor(AggregatorInterface _usdOracle, uint256[] memory _rentPrices)
public
{
usdOracle = _usdOracle;
setPrices(_rentPrices);
}
function price(
string calldata name,
uint256 expires,
uint256 duration
) external view override returns (uint256) {
uint256 len = name.strlen();
if (len > rentPrices.length) {
len = rentPrices.length;
}
require(len > 0);
uint256 basePrice = rentPrices[len - 1].mul(duration);
basePrice = basePrice.add(_premium(name, expires, duration));
return attoUSDToWei(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, equal to one attodollar (1e-18
* dollar) each.
*/
function setPrices(uint256[] memory _rentPrices) public onlyOwner {
rentPrices = _rentPrices;
emit RentPriceChanged(_rentPrices);
}
/**
* @dev Returns the pricing premium in wei.
*/
function premium(
string calldata name,
uint256 expires,
uint256 duration
) external view returns (uint256) {
uint256 weiPrice = attoUSDToWei(_premium(name, expires, duration));
return weiPrice;
}
/**
* @dev Returns the pricing premium in internal base units.
*/
function _premium(
string memory name,
uint256 expires,
uint256 duration
) internal view virtual returns (uint256) {
return 0;
}
function attoUSDToWei(uint256 amount) internal view returns (uint256) {
uint256 ethPrice = uint256(usdOracle.latestAnswer()); //2
return amount.mul(1e8).div(ethPrice);
}
function weiToAttoUSD(uint256 amount) internal view returns (uint256) {
uint256 ethPrice = uint256(usdOracle.latestAnswer());
return amount.mul(ethPrice).div(1e8);
}
function supportsInterface(bytes4 interfaceID)
public
view
virtual
returns (bool)
{
return interfaceID == INTERFACE_META_ID || interfaceID == ORACLE_ID;
}
}
Read Contract
decayedPremium 0x59e1777c → uint256
owner 0x8da5cb5b → address
premium 0xa34e3596 → uint256
price 0x50e9a715 → uint256
rentPrices 0x06d5d0b6 → uint256
supportsInterface 0x01ffc9a7 → bool
usdOracle 0xc8a4271f → address
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
renounceOwnership 0x715018a6
No parameters
setPrices 0x79cf92d3
uint256[] _rentPrices
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address