Address Contract Partially Verified
Address
0xE59dbF08CccF8D1ab90156b9664d31Fd20BB2AC7
Balance
0 ETH
Nonce
1
Code Size
1527 bytes
Creator
0x54b5Aae5...F4ad at tx 0xa889b19a...99ce75
Indexed Transactions
0 (1 on-chain, 0.7% indexed)
Contract Bytecode
1527 bytes
0x608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b146100ce578063e30c3978146100f3578063e8c7e72814610104578063f2fde38b1461010c57600080fd5b80635b2ec32b1461008d5780636c7c1cbb146100a2578063715018a6146100be57806379ba5097146100c6575b600080fd5b6100a061009b366004610429565b61011f565b005b6100ab60025481565b6040519081526020015b60405180910390f35b6100a061019c565b6100a06101d2565b6000546001600160a01b03165b6040516001600160a01b0390911681526020016100b5565b6001546001600160a01b03166100db565b6100a061024c565b6100a061011a366004610442565b6102ae565b6000546001600160a01b031633146101525760405162461bcd60e51b81526004016101499061046b565b60405180910390fd5b61015b81610391565b60025460408051918252602082018390527fabb7cb8904df4b6cf0918b8b3ba9ccc27f9750eaf04f9a78507ead12babdabc8910160405180910390a1600255565b6000546001600160a01b031633146101c65760405162461bcd60e51b81526004016101499061046b565b6101d060006103d5565b565b60015433906001600160a01b031681146102405760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610149565b610249816103d5565b50565b600080600254121561027557600254610264906104b6565b61026e90426104d2565b9050610285565b60025461028290426104eb565b90505b6006610290826103ee565b106102495760405163374b0d0760e11b815260040160405180910390fd5b6000546001600160a01b031633146102d85760405162461bcd60e51b81526004016101499061046b565b600180546001600160a01b0383166001600160a01b031990911681179091556103096000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61039f610e10600b196104fe565b8112806103b757506103b4610e10600e6104fe565b81135b156102495760405163025d6fbf60e41b815260040160405180910390fd5b600180546001600160a01b031916905561024981610341565b6000806103fe6201518084610599565b9050600761040d8260036104eb565b61041791906105ad565b6104229060016104eb565b9392505050565b60006020828403121561043b57600080fd5b5035919050565b60006020828403121561045457600080fd5b81356001600160a01b038116811461042257600080fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b82016104cb576104cb6104a0565b5060000390565b818103818111156104e5576104e56104a0565b92915050565b808201808211156104e5576104e56104a0565b60006001600160ff1b0381841382841380821686840486111615610524576105246104a0565b600160ff1b6000871282811687830589121615610543576105436104a0565b6000871292508782058712848416161561055f5761055f6104a0565b87850587128184161615610575576105756104a0565b505050929093029392505050565b634e487b7160e01b600052601260045260246000fd5b6000826105a8576105a8610583565b500490565b6000826105bc576105bc610583565b50069056fea2646970667358221220307824cae27e6ba53caf59f820126c8ba0191c74177a7bee6afe43ca5cc9e9de64736f6c63430008100033
Verified Source Code Partial Match
Compiler: v0.8.16+commit.07a7930e
EVM: london
Optimization: Yes (200 runs)
IssuanceHours.sol 112 lines
/**SPDX-License-Identifier: BUSL-1.1
▄▄█████████▄
╓██▀└ ,╓▄▄▄, '▀██▄
██▀ ▄██▀▀╙╙▀▀██▄ └██µ ,, ,, , ,,, ,,,
██ ,██¬ ▄████▄ ▀█▄ ╙█▄ ▄███▀▀███▄ ███▄ ██ ███▀▀▀███▄ ▄███▀▀███,
██ ██ ╒█▀' ╙█▌ ╙█▌ ██ ▐██ ███ █████, ██ ██▌ └██▌ ██▌ └██▌
██ ▐█▌ ██ ╟█ █▌ ╟█ ██▌ ▐██ ██ └███ ██ ██▌ ╟██ j██ ╟██
╟█ ██ ╙██ ▄█▀ ▐█▌ ██ ╙██ ██▌ ██ ╙████ ██▌ ▄██▀ ██▌ ,██▀
██ "██, ╙▀▀███████████⌐ ╙████████▀ ██ ╙██ ███████▀▀ ╙███████▀`
██▄ ╙▀██▄▄▄▄▄,,, ¬─ '─¬
╙▀██▄ '╙╙╙▀▀▀▀▀▀▀▀
╙▀▀██████R⌐
*/
pragma solidity 0.8.16;
import "contracts/globalMarkets/tokenManager/issuanceHours/IIssuanceHours.sol";
import "contracts/external/openzeppelin/contracts/access/Ownable2Step.sol";
import "contracts/external/openzeppelin/contracts/access/Ownable.sol";
import "contracts/external/BokkyPooBahsDateTimeLibrary/BokkyPooBahsDateTimeLibrary.sol";
/**
* @title IssuanceHours
* @author Ondo Finance
* @notice This contract is used to check if the current time is within the
* issuance hours for a given market. The issuance hours are defined
* as Monday to Friday 24/5.
*
* @dev This is a naive layer of protection for defense-in-depth, and should not be
* relied upon for any critical functionality. It is intended to be used as
* a fail safe for the quoting engine signing invalid attestations.
*/
contract IssuanceHours is IIssuanceHours, Ownable2Step {
/// The timezone offset in seconds from UTC. Can be negative (west of UTC) or positive (east of UTC)
int256 public timezoneOffset;
/// Constant for the number of seconds in an hour
int256 constant HOUR_IN_SECONDS = 3_600;
/**
* @notice Event emitted when the timezone offset is set
* @param prevTimezoneOffset The previous timezone offset in seconds from UTC
* @param newTimezoneOffset The new timezone offset in seconds from UTC
*/
event SetTimezoneOffset(int256 prevTimezoneOffset, int256 newTimezoneOffset);
/// Error emitted when the current time is not within the issuance hours
error OutsideMarketHours();
/// Error emitted when the timezone offset exceeds the maximum allowed value
error MaximumOffsetExceeded();
/**
* @notice Constructor for the MarketIssuanceHours contract
* @param admin The address of the admin for the contract
* @param _timezoneOffset The timezone offset in seconds from UTC
* @dev The timezone offset is used to determine the issuance hours for
* the market.
*/
constructor(address admin, int256 _timezoneOffset) {
_validateTimezoneOffset(_timezoneOffset);
timezoneOffset = _timezoneOffset;
_transferOwnership(admin);
}
/**
* @notice Check if the current time is within the market hours
* @dev The function computes the day of the week based on the current block timestamp
* and checks if it is within the issuance hours. This does ignore holidays as it
* is only intended to be a fail safe for the quoting engine signing invalid attestations.
*/
function checkIsValidHours() external view {
uint256 adjustedTimestamp;
if (timezoneOffset < 0) {
adjustedTimestamp = block.timestamp - uint256(-timezoneOffset);
} else {
adjustedTimestamp = block.timestamp + uint256(timezoneOffset);
}
if (BokkyPooBahsDateTimeLibrary.getDayOfWeek(adjustedTimestamp) >= 6) {
revert OutsideMarketHours();
}
}
/**
* @notice Set the timezone offset in seconds from UTC
* @param _timezoneOffset The new timezone offset in seconds from UTC
* @dev This function can only be called by the owner of the contract
*/
function setTimezoneOffset(int256 _timezoneOffset) public onlyOwner {
_validateTimezoneOffset(_timezoneOffset);
emit SetTimezoneOffset(timezoneOffset, _timezoneOffset);
timezoneOffset = _timezoneOffset;
}
/**
* @notice Validate the timezone offset
* @param _timezoneOffset The timezone offset in seconds from UTC
* @dev This function checks if the timezone offset is within the allowed range
* of -12 to +14 hours. If it is not, it reverts with MaximumOffsetExceeded error.
*/
function _validateTimezoneOffset(int256 _timezoneOffset) private pure {
if (
_timezoneOffset < -12 * HOUR_IN_SECONDS ||
_timezoneOffset > 14 * HOUR_IN_SECONDS
) revert MaximumOffsetExceeded();
}
}
IIssuanceHours.sol 24 lines
// SPDX-License-Identifier: BUSL-1.1
/*
▄▄█████████▄
╓██▀└ ,╓▄▄▄, '▀██▄
██▀ ▄██▀▀╙╙▀▀██▄ └██µ ,, ,, , ,,, ,,,
██ ,██¬ ▄████▄ ▀█▄ ╙█▄ ▄███▀▀███▄ ███▄ ██ ███▀▀▀███▄ ▄███▀▀███,
██ ██ ╒█▀' ╙█▌ ╙█▌ ██ ▐██ ███ █████, ██ ██▌ └██▌ ██▌ └██▌
██ ▐█▌ ██ ╟█ █▌ ╟█ ██▌ ▐██ ██ └███ ██ ██▌ ╟██ j██ ╟██
╟█ ██ ╙██ ▄█▀ ▐█▌ ██ ╙██ ██▌ ██ ╙████ ██▌ ▄██▀ ██▌ ,██▀
██ "██, ╙▀▀███████████⌐ ╙████████▀ ██ ╙██ ███████▀▀ ╙███████▀`
██▄ ╙▀██▄▄▄▄▄,,, ¬─ '─¬
╙▀██▄ '╙╙╙▀▀▀▀▀▀▀▀
╙▀▀██████R⌐
*/
pragma solidity 0.8.16;
/**
* @title IIssuanceHours
* @author Ondo Finance
* @notice Interface for checking if current time is within valid market hours
*/
interface IIssuanceHours {
function checkIsValidHours() external;
}
Ownable2Step.sol 57 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.0;
import "./Ownable.sol";
/**
* @dev Contract module which provides 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} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
}
Ownable.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "contracts/external/openzeppelin/contracts/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);
}
}
BokkyPooBahsDateTimeLibrary.sol 443 lines
// SPDX-License-Identifier: MIT
// https://raw.githubusercontent.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/1dc26f977c57a6ba3ed6d7c53cafdb191e7e59ae/contracts/BokkyPooBahsDateTimeLibrary.sol
pragma solidity >=0.6.0 <0.9.0;
// ----------------------------------------------------------------------------
// BokkyPooBah's DateTime Library v1.01
//
// A gas-efficient Solidity date and time library
//
// https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
//
// Tested date range 1970/01/01 to 2345/12/31
//
// Conventions:
// Unit | Range | Notes
// :-------- |:-------------:|:-----
// timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
// year | 1970 ... 2345 |
// month | 1 ... 12 |
// day | 1 ... 31 |
// hour | 0 ... 23 |
// minute | 0 ... 59 |
// second | 0 ... 59 |
// dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
// ----------------------------------------------------------------------------
library BokkyPooBahsDateTimeLibrary {
uint constant SECONDS_PER_DAY = 24 * 60 * 60;
uint constant SECONDS_PER_HOUR = 60 * 60;
uint constant SECONDS_PER_MINUTE = 60;
int constant OFFSET19700101 = 2440588;
uint constant DOW_MON = 1;
uint constant DOW_TUE = 2;
uint constant DOW_WED = 3;
uint constant DOW_THU = 4;
uint constant DOW_FRI = 5;
uint constant DOW_SAT = 6;
uint constant DOW_SUN = 7;
// ------------------------------------------------------------------------
// Calculate the number of days from 1970/01/01 to year/month/day using
// the date conversion algorithm from
// https://aa.usno.navy.mil/faq/JD_formula.html
// and subtracting the offset 2440588 so that 1970/01/01 is day 0
//
// days = day
// - 32075
// + 1461 * (year + 4800 + (month - 14) / 12) / 4
// + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
// - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
// - offset
// ------------------------------------------------------------------------
function _daysFromDate(
uint year,
uint month,
uint day
) internal pure returns (uint _days) {
require(year >= 1970);
int _year = int(year);
int _month = int(month);
int _day = int(day);
int __days = _day -
32075 +
(1461 * (_year + 4800 + (_month - 14) / 12)) /
4 +
(367 * (_month - 2 - ((_month - 14) / 12) * 12)) /
12 -
(3 * ((_year + 4900 + (_month - 14) / 12) / 100)) /
4 -
OFFSET19700101;
_days = uint(__days);
}
// ------------------------------------------------------------------------
// Calculate year/month/day from the number of days since 1970/01/01 using
// the date conversion algorithm from
// http://aa.usno.navy.mil/faq/docs/JD_Formula.php
// and adding the offset 2440588 so that 1970/01/01 is day 0
//
// int L = days + 68569 + offset
// int N = 4 * L / 146097
// L = L - (146097 * N + 3) / 4
// year = 4000 * (L + 1) / 1461001
// L = L - 1461 * year / 4 + 31
// month = 80 * L / 2447
// dd = L - 2447 * month / 80
// L = month / 11
// month = month + 2 - 12 * L
// year = 100 * (N - 49) + year + L
// ------------------------------------------------------------------------
function _daysToDate(
uint _days
) internal pure returns (uint year, uint month, uint day) {
int __days = int(_days);
int L = __days + 68569 + OFFSET19700101;
int N = (4 * L) / 146097;
L = L - (146097 * N + 3) / 4;
int _year = (4000 * (L + 1)) / 1461001;
L = L - (1461 * _year) / 4 + 31;
int _month = (80 * L) / 2447;
int _day = L - (2447 * _month) / 80;
L = _month / 11;
_month = _month + 2 - 12 * L;
_year = 100 * (N - 49) + _year + L;
year = uint(_year);
month = uint(_month);
day = uint(_day);
}
function timestampFromDate(
uint year,
uint month,
uint day
) internal pure returns (uint timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
}
function timestampFromDateTime(
uint year,
uint month,
uint day,
uint hour,
uint minute,
uint second
) internal pure returns (uint timestamp) {
timestamp =
_daysFromDate(year, month, day) *
SECONDS_PER_DAY +
hour *
SECONDS_PER_HOUR +
minute *
SECONDS_PER_MINUTE +
second;
}
function timestampToDate(
uint timestamp
) internal pure returns (uint year, uint month, uint day) {
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function timestampToDateTime(
uint timestamp
)
internal
pure
returns (
uint year,
uint month,
uint day,
uint hour,
uint minute,
uint second
)
{
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
secs = secs % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
second = secs % SECONDS_PER_MINUTE;
}
function isValidDate(
uint year,
uint month,
uint day
) internal pure returns (bool valid) {
if (year >= 1970 && month > 0 && month <= 12) {
uint daysInMonth = _getDaysInMonth(year, month);
if (day > 0 && day <= daysInMonth) {
valid = true;
}
}
}
function isValidDateTime(
uint year,
uint month,
uint day,
uint hour,
uint minute,
uint second
) internal pure returns (bool valid) {
if (isValidDate(year, month, day)) {
if (hour < 24 && minute < 60 && second < 60) {
valid = true;
}
}
}
function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
(uint year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY);
leapYear = _isLeapYear(year);
}
function _isLeapYear(uint year) internal pure returns (bool leapYear) {
leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
}
function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
}
function getDaysInMonth(
uint timestamp
) internal pure returns (uint daysInMonth) {
(uint year, uint month, ) = _daysToDate(timestamp / SECONDS_PER_DAY);
daysInMonth = _getDaysInMonth(year, month);
}
function _getDaysInMonth(
uint year,
uint month
) internal pure returns (uint daysInMonth) {
if (
month == 1 ||
month == 3 ||
month == 5 ||
month == 7 ||
month == 8 ||
month == 10 ||
month == 12
) {
daysInMonth = 31;
} else if (month != 2) {
daysInMonth = 30;
} else {
daysInMonth = _isLeapYear(year) ? 29 : 28;
}
}
// 1 = Monday, 7 = Sunday
function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
uint _days = timestamp / SECONDS_PER_DAY;
dayOfWeek = ((_days + 3) % 7) + 1;
}
function getYear(uint timestamp) internal pure returns (uint year) {
(year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getMonth(uint timestamp) internal pure returns (uint month) {
(, month, ) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getDay(uint timestamp) internal pure returns (uint day) {
(, , day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getHour(uint timestamp) internal pure returns (uint hour) {
uint secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
}
function getMinute(uint timestamp) internal pure returns (uint minute) {
uint secs = timestamp % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
}
function getSecond(uint timestamp) internal pure returns (uint second) {
second = timestamp % SECONDS_PER_MINUTE;
}
function addYears(
uint timestamp,
uint _years
) internal pure returns (uint newTimestamp) {
(uint year, uint month, uint day) = _daysToDate(
timestamp / SECONDS_PER_DAY
);
year += _years;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp =
_daysFromDate(year, month, day) *
SECONDS_PER_DAY +
(timestamp % SECONDS_PER_DAY);
require(newTimestamp >= timestamp);
}
function addMonths(
uint timestamp,
uint _months
) internal pure returns (uint newTimestamp) {
(uint year, uint month, uint day) = _daysToDate(
timestamp / SECONDS_PER_DAY
);
month += _months;
year += (month - 1) / 12;
month = ((month - 1) % 12) + 1;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp =
_daysFromDate(year, month, day) *
SECONDS_PER_DAY +
(timestamp % SECONDS_PER_DAY);
require(newTimestamp >= timestamp);
}
function addDays(
uint timestamp,
uint _days
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _days * SECONDS_PER_DAY;
require(newTimestamp >= timestamp);
}
function addHours(
uint timestamp,
uint _hours
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
require(newTimestamp >= timestamp);
}
function addMinutes(
uint timestamp,
uint _minutes
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
require(newTimestamp >= timestamp);
}
function addSeconds(
uint timestamp,
uint _seconds
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _seconds;
require(newTimestamp >= timestamp);
}
function subYears(
uint timestamp,
uint _years
) internal pure returns (uint newTimestamp) {
(uint year, uint month, uint day) = _daysToDate(
timestamp / SECONDS_PER_DAY
);
year -= _years;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp =
_daysFromDate(year, month, day) *
SECONDS_PER_DAY +
(timestamp % SECONDS_PER_DAY);
require(newTimestamp <= timestamp);
}
function subMonths(
uint timestamp,
uint _months
) internal pure returns (uint newTimestamp) {
(uint year, uint month, uint day) = _daysToDate(
timestamp / SECONDS_PER_DAY
);
uint yearMonth = year * 12 + (month - 1) - _months;
year = yearMonth / 12;
month = (yearMonth % 12) + 1;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp =
_daysFromDate(year, month, day) *
SECONDS_PER_DAY +
(timestamp % SECONDS_PER_DAY);
require(newTimestamp <= timestamp);
}
function subDays(
uint timestamp,
uint _days
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _days * SECONDS_PER_DAY;
require(newTimestamp <= timestamp);
}
function subHours(
uint timestamp,
uint _hours
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
require(newTimestamp <= timestamp);
}
function subMinutes(
uint timestamp,
uint _minutes
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
require(newTimestamp <= timestamp);
}
function subSeconds(
uint timestamp,
uint _seconds
) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _seconds;
require(newTimestamp <= timestamp);
}
function diffYears(
uint fromTimestamp,
uint toTimestamp
) internal pure returns (uint _years) {
require(fromTimestamp <= toTimestamp);
(uint fromYear, , ) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
(uint toYear, , ) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_years = toYear - fromYear;
}
function diffMonths(
uint fromTimestamp,
uint toTimestamp
) internal pure returns (uint _months) {
require(fromTimestamp <= toTimestamp);
(uint fromYear, uint fromMonth, ) = _daysToDate(
fromTimestamp / SECONDS_PER_DAY
);
(uint toYear, uint toMonth, ) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
}
function diffDays(
uint fromTimestamp,
uint toTimestamp
) internal pure returns (uint _days) {
require(fromTimestamp <= toTimestamp);
_days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
}
function diffHours(
uint fromTimestamp,
uint toTimestamp
) internal pure returns (uint _hours) {
require(fromTimestamp <= toTimestamp);
_hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
}
function diffMinutes(
uint fromTimestamp,
uint toTimestamp
) internal pure returns (uint _minutes) {
require(fromTimestamp <= toTimestamp);
_minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
}
function diffSeconds(
uint fromTimestamp,
uint toTimestamp
) internal pure returns (uint _seconds) {
require(fromTimestamp <= toTimestamp);
_seconds = toTimestamp - fromTimestamp;
}
}
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;
}
}
Read Contract
checkIsValidHours 0xe8c7e728
owner 0x8da5cb5b → address
pendingOwner 0xe30c3978 → address
timezoneOffset 0x6c7c1cbb → int256
Write Contract 4 functions
These functions modify contract state and require a wallet transaction to execute.
acceptOwnership 0x79ba5097
No parameters
renounceOwnership 0x715018a6
No parameters
setTimezoneOffset 0x5b2ec32b
int256 _timezoneOffset
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
This address has 1 on-chain transactions, but only 0.7% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →