编译器
0.8.19+commit.7dd6d404
文件 1 的 40:AddressUtils.sol
pragma solidity ^0.8.8;
import { UintUtils } from './UintUtils.sol';
library AddressUtils {
using UintUtils for uint256;
error AddressUtils__InsufficientBalance();
error AddressUtils__NotContract();
error AddressUtils__SendValueFailed();
function toString(address account) internal pure returns (string memory) {
return uint256(uint160(account)).toHexString(20);
}
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable account, uint256 amount) internal {
(bool success, ) = account.call{ value: amount }('');
if (!success) revert AddressUtils__SendValueFailed();
}
function functionCall(
address target,
bytes memory data
) internal returns (bytes memory) {
return
functionCall(target, data, 'AddressUtils: failed low-level call');
}
function functionCall(
address target,
bytes memory data,
string memory error
) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, error);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
'AddressUtils: failed low-level call with value'
);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory error
) internal returns (bytes memory) {
if (value > address(this).balance)
revert AddressUtils__InsufficientBalance();
return _functionCallWithValue(target, data, value, error);
}
function excessivelySafeCall(
address target,
uint256 gasAmount,
uint256 value,
uint16 maxCopy,
bytes memory data
) internal returns (bool success, bytes memory returnData) {
returnData = new bytes(maxCopy);
assembly {
success := call(
gasAmount,
target,
value,
add(data, 0x20),
mload(data),
0,
0
)
let toCopy := returndatasize()
if gt(toCopy, maxCopy) {
toCopy := maxCopy
}
mstore(returnData, toCopy)
returndatacopy(add(returnData, 0x20), 0, toCopy)
}
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory error
) private returns (bytes memory) {
if (!isContract(target)) revert AddressUtils__NotContract();
(bool success, bytes memory returnData) = target.call{ value: value }(
data
);
if (success) {
return returnData;
} else if (returnData.length > 0) {
assembly {
let returnData_size := mload(returnData)
revert(add(32, returnData), returnData_size)
}
} else {
revert(error);
}
}
}
文件 2 的 40:BokkyPooBahsDateTimeLibrary.sol
pragma solidity >=0.6.0 <0.9.0;
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;
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);
}
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;
}
}
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;
}
}
文件 3 的 40:Casting.sol
pragma solidity >=0.8.19;
import "./Errors.sol" as CastingErrors;
import { MAX_UINT128, MAX_UINT40 } from "../Common.sol";
import { uMAX_SD1x18, uMIN_SD1x18 } from "../sd1x18/Constants.sol";
import { SD1x18 } from "../sd1x18/ValueType.sol";
import { uMAX_UD2x18 } from "../ud2x18/Constants.sol";
import { UD2x18 } from "../ud2x18/ValueType.sol";
import { UD60x18 } from "../ud60x18/ValueType.sol";
import { SD59x18 } from "./ValueType.sol";
function intoInt256(SD59x18 x) pure returns (int256 result) {
result = SD59x18.unwrap(x);
}
function intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {
int256 xInt = SD59x18.unwrap(x);
if (xInt < uMIN_SD1x18) {
revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);
}
if (xInt > uMAX_SD1x18) {
revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);
}
result = SD1x18.wrap(int64(xInt));
}
function intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {
int256 xInt = SD59x18.unwrap(x);
if (xInt < 0) {
revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);
}
if (xInt > int256(uint256(uMAX_UD2x18))) {
revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);
}
result = UD2x18.wrap(uint64(uint256(xInt)));
}
function intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {
int256 xInt = SD59x18.unwrap(x);
if (xInt < 0) {
revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);
}
result = UD60x18.wrap(uint256(xInt));
}
function intoUint256(SD59x18 x) pure returns (uint256 result) {
int256 xInt = SD59x18.unwrap(x);
if (xInt < 0) {
revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);
}
result = uint256(xInt);
}
function intoUint128(SD59x18 x) pure returns (uint128 result) {
int256 xInt = SD59x18.unwrap(x);
if (xInt < 0) {
revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);
}
if (xInt > int256(uint256(MAX_UINT128))) {
revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);
}
result = uint128(uint256(xInt));
}
function intoUint40(SD59x18 x) pure returns (uint40 result) {
int256 xInt = SD59x18.unwrap(x);
if (xInt < 0) {
revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);
}
if (xInt > int256(uint256(MAX_UINT40))) {
revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);
}
result = uint40(uint256(xInt));
}
function sd(int256 x) pure returns (SD59x18 result) {
result = SD59x18.wrap(x);
}
function sd59x18(int256 x) pure returns (SD59x18 result) {
result = SD59x18.wrap(x);
}
function unwrap(SD59x18 x) pure returns (int256 result) {
result = SD59x18.unwrap(x);
}
function wrap(int256 x) pure returns (SD59x18 result) {
result = SD59x18.wrap(x);
}
文件 4 的 40:Common.sol
pragma solidity >=0.8.19;
error PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);
error PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);
error PRBMath_MulDivSigned_InputTooSmall();
error PRBMath_MulDivSigned_Overflow(int256 x, int256 y);
uint128 constant MAX_UINT128 = type(uint128).max;
uint40 constant MAX_UINT40 = type(uint40).max;
uint256 constant UNIT = 1e18;
uint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;
uint256 constant UNIT_LPOTD = 262144;
function exp2(uint256 x) pure returns (uint256 result) {
unchecked {
result = 0x800000000000000000000000000000000000000000000000;
if (x & 0xFF00000000000000 > 0) {
if (x & 0x8000000000000000 > 0) {
result = (result * 0x16A09E667F3BCC909) >> 64;
}
if (x & 0x4000000000000000 > 0) {
result = (result * 0x1306FE0A31B7152DF) >> 64;
}
if (x & 0x2000000000000000 > 0) {
result = (result * 0x1172B83C7D517ADCE) >> 64;
}
if (x & 0x1000000000000000 > 0) {
result = (result * 0x10B5586CF9890F62A) >> 64;
}
if (x & 0x800000000000000 > 0) {
result = (result * 0x1059B0D31585743AE) >> 64;
}
if (x & 0x400000000000000 > 0) {
result = (result * 0x102C9A3E778060EE7) >> 64;
}
if (x & 0x200000000000000 > 0) {
result = (result * 0x10163DA9FB33356D8) >> 64;
}
if (x & 0x100000000000000 > 0) {
result = (result * 0x100B1AFA5ABCBED61) >> 64;
}
}
if (x & 0xFF000000000000 > 0) {
if (x & 0x80000000000000 > 0) {
result = (result * 0x10058C86DA1C09EA2) >> 64;
}
if (x & 0x40000000000000 > 0) {
result = (result * 0x1002C605E2E8CEC50) >> 64;
}
if (x & 0x20000000000000 > 0) {
result = (result * 0x100162F3904051FA1) >> 64;
}
if (x & 0x10000000000000 > 0) {
result = (result * 0x1000B175EFFDC76BA) >> 64;
}
if (x & 0x8000000000000 > 0) {
result = (result * 0x100058BA01FB9F96D) >> 64;
}
if (x & 0x4000000000000 > 0) {
result = (result * 0x10002C5CC37DA9492) >> 64;
}
if (x & 0x2000000000000 > 0) {
result = (result * 0x1000162E525EE0547) >> 64;
}
if (x & 0x1000000000000 > 0) {
result = (result * 0x10000B17255775C04) >> 64;
}
}
if (x & 0xFF0000000000 > 0) {
if (x & 0x800000000000 > 0) {
result = (result * 0x1000058B91B5BC9AE) >> 64;
}
if (x & 0x400000000000 > 0) {
result = (result * 0x100002C5C89D5EC6D) >> 64;
}
if (x & 0x200000000000 > 0) {
result = (result * 0x10000162E43F4F831) >> 64;
}
if (x & 0x100000000000 > 0) {
result = (result * 0x100000B1721BCFC9A) >> 64;
}
if (x & 0x80000000000 > 0) {
result = (result * 0x10000058B90CF1E6E) >> 64;
}
if (x & 0x40000000000 > 0) {
result = (result * 0x1000002C5C863B73F) >> 64;
}
if (x & 0x20000000000 > 0) {
result = (result * 0x100000162E430E5A2) >> 64;
}
if (x & 0x10000000000 > 0) {
result = (result * 0x1000000B172183551) >> 64;
}
}
if (x & 0xFF00000000 > 0) {
if (x & 0x8000000000 > 0) {
result = (result * 0x100000058B90C0B49) >> 64;
}
if (x & 0x4000000000 > 0) {
result = (result * 0x10000002C5C8601CC) >> 64;
}
if (x & 0x2000000000 > 0) {
result = (result * 0x1000000162E42FFF0) >> 64;
}
if (x & 0x1000000000 > 0) {
result = (result * 0x10000000B17217FBB) >> 64;
}
if (x & 0x800000000 > 0) {
result = (result * 0x1000000058B90BFCE) >> 64;
}
if (x & 0x400000000 > 0) {
result = (result * 0x100000002C5C85FE3) >> 64;
}
if (x & 0x200000000 > 0) {
result = (result * 0x10000000162E42FF1) >> 64;
}
if (x & 0x100000000 > 0) {
result = (result * 0x100000000B17217F8) >> 64;
}
}
if (x & 0xFF000000 > 0) {
if (x & 0x80000000 > 0) {
result = (result * 0x10000000058B90BFC) >> 64;
}
if (x & 0x40000000 > 0) {
result = (result * 0x1000000002C5C85FE) >> 64;
}
if (x & 0x20000000 > 0) {
result = (result * 0x100000000162E42FF) >> 64;
}
if (x & 0x10000000 > 0) {
result = (result * 0x1000000000B17217F) >> 64;
}
if (x & 0x8000000 > 0) {
result = (result * 0x100000000058B90C0) >> 64;
}
if (x & 0x4000000 > 0) {
result = (result * 0x10000000002C5C860) >> 64;
}
if (x & 0x2000000 > 0) {
result = (result * 0x1000000000162E430) >> 64;
}
if (x & 0x1000000 > 0) {
result = (result * 0x10000000000B17218) >> 64;
}
}
if (x & 0xFF0000 > 0) {
if (x & 0x800000 > 0) {
result = (result * 0x1000000000058B90C) >> 64;
}
if (x & 0x400000 > 0) {
result = (result * 0x100000000002C5C86) >> 64;
}
if (x & 0x200000 > 0) {
result = (result * 0x10000000000162E43) >> 64;
}
if (x & 0x100000 > 0) {
result = (result * 0x100000000000B1721) >> 64;
}
if (x & 0x80000 > 0) {
result = (result * 0x10000000000058B91) >> 64;
}
if (x & 0x40000 > 0) {
result = (result * 0x1000000000002C5C8) >> 64;
}
if (x & 0x20000 > 0) {
result = (result * 0x100000000000162E4) >> 64;
}
if (x & 0x10000 > 0) {
result = (result * 0x1000000000000B172) >> 64;
}
}
if (x & 0xFF00 > 0) {
if (x & 0x8000 > 0) {
result = (result * 0x100000000000058B9) >> 64;
}
if (x & 0x4000 > 0) {
result = (result * 0x10000000000002C5D) >> 64;
}
if (x & 0x2000 > 0) {
result = (result * 0x1000000000000162E) >> 64;
}
if (x & 0x1000 > 0) {
result = (result * 0x10000000000000B17) >> 64;
}
if (x & 0x800 > 0) {
result = (result * 0x1000000000000058C) >> 64;
}
if (x & 0x400 > 0) {
result = (result * 0x100000000000002C6) >> 64;
}
if (x & 0x200 > 0) {
result = (result * 0x10000000000000163) >> 64;
}
if (x & 0x100 > 0) {
result = (result * 0x100000000000000B1) >> 64;
}
}
if (x & 0xFF > 0) {
if (x & 0x80 > 0) {
result = (result * 0x10000000000000059) >> 64;
}
if (x & 0x40 > 0) {
result = (result * 0x1000000000000002C) >> 64;
}
if (x & 0x20 > 0) {
result = (result * 0x10000000000000016) >> 64;
}
if (x & 0x10 > 0) {
result = (result * 0x1000000000000000B) >> 64;
}
if (x & 0x8 > 0) {
result = (result * 0x10000000000000006) >> 64;
}
if (x & 0x4 > 0) {
result = (result * 0x10000000000000003) >> 64;
}
if (x & 0x2 > 0) {
result = (result * 0x10000000000000001) >> 64;
}
if (x & 0x1 > 0) {
result = (result * 0x10000000000000001) >> 64;
}
}
result *= UNIT;
result >>= (191 - (x >> 64));
}
}
function msb(uint256 x) pure returns (uint256 result) {
assembly ("memory-safe") {
let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(5, gt(x, 0xFFFFFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(4, gt(x, 0xFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(3, gt(x, 0xFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(2, gt(x, 0xF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(1, gt(x, 0x3))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := gt(x, 0x1)
result := or(result, factor)
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly ("memory-safe") {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
unchecked {
return prod0 / denominator;
}
}
if (prod1 >= denominator) {
revert PRBMath_MulDiv_Overflow(x, y, denominator);
}
uint256 remainder;
assembly ("memory-safe") {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
unchecked {
uint256 lpotdod = denominator & (~denominator + 1);
uint256 flippedLpotdod;
assembly ("memory-safe") {
denominator := div(denominator, lpotdod)
prod0 := div(prod0, lpotdod)
flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)
}
prod0 |= prod1 * flippedLpotdod;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
}
}
function mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly ("memory-safe") {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
unchecked {
return prod0 / UNIT;
}
}
if (prod1 >= UNIT) {
revert PRBMath_MulDiv18_Overflow(x, y);
}
uint256 remainder;
assembly ("memory-safe") {
remainder := mulmod(x, y, UNIT)
result :=
mul(
or(
div(sub(prod0, remainder), UNIT_LPOTD),
mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))
),
UNIT_INVERSE
)
}
}
function mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {
if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {
revert PRBMath_MulDivSigned_InputTooSmall();
}
uint256 xAbs;
uint256 yAbs;
uint256 dAbs;
unchecked {
xAbs = x < 0 ? uint256(-x) : uint256(x);
yAbs = y < 0 ? uint256(-y) : uint256(y);
dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);
}
uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);
if (resultAbs > uint256(type(int256).max)) {
revert PRBMath_MulDivSigned_Overflow(x, y);
}
uint256 sx;
uint256 sy;
uint256 sd;
assembly ("memory-safe") {
sx := sgt(x, sub(0, 1))
sy := sgt(y, sub(0, 1))
sd := sgt(denominator, sub(0, 1))
}
unchecked {
result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);
}
}
function sqrt(uint256 x) pure returns (uint256 result) {
if (x == 0) {
return 0;
}
uint256 xAux = uint256(x);
result = 1;
if (xAux >= 2 ** 128) {
xAux >>= 128;
result <<= 64;
}
if (xAux >= 2 ** 64) {
xAux >>= 64;
result <<= 32;
}
if (xAux >= 2 ** 32) {
xAux >>= 32;
result <<= 16;
}
if (xAux >= 2 ** 16) {
xAux >>= 16;
result <<= 8;
}
if (xAux >= 2 ** 8) {
xAux >>= 8;
result <<= 4;
}
if (xAux >= 2 ** 4) {
xAux >>= 4;
result <<= 2;
}
if (xAux >= 2 ** 2) {
result <<= 1;
}
unchecked {
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
uint256 roundedDownResult = x / result;
if (result >= roundedDownResult) {
result = roundedDownResult;
}
}
}
文件 5 的 40:Constants.sol
pragma solidity >=0.8.19;
import { SD1x18 } from "./ValueType.sol";
SD1x18 constant E = SD1x18.wrap(2_718281828459045235);
int64 constant uMAX_SD1x18 = 9_223372036854775807;
SD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);
int64 constant uMIN_SD1x18 = -9_223372036854775808;
SD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);
SD1x18 constant PI = SD1x18.wrap(3_141592653589793238);
SD1x18 constant UNIT = SD1x18.wrap(1e18);
int256 constant uUNIT = 1e18;
文件 6 的 40:Conversions.sol
pragma solidity >=0.8.19;
import { uMAX_UD60x18, uUNIT } from "./Constants.sol";
import { PRBMath_UD60x18_Convert_Overflow } from "./Errors.sol";
import { UD60x18 } from "./ValueType.sol";
function convert(UD60x18 x) pure returns (uint256 result) {
result = UD60x18.unwrap(x) / uUNIT;
}
function convert(uint256 x) pure returns (UD60x18 result) {
if (x > uMAX_UD60x18 / uUNIT) {
revert PRBMath_UD60x18_Convert_Overflow(x);
}
unchecked {
result = UD60x18.wrap(x * uUNIT);
}
}
文件 7 的 40:ERC165BaseInternal.sol
pragma solidity ^0.8.8;
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';
abstract contract ERC165BaseInternal is IERC165BaseInternal {
function _supportsInterface(
bytes4 interfaceId
) internal view virtual returns (bool) {
return ERC165BaseStorage.layout().supportedInterfaces[interfaceId];
}
function _setSupportsInterface(
bytes4 interfaceId,
bool status
) internal virtual {
if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
}
}
文件 8 的 40:ERC165BaseStorage.sol
pragma solidity ^0.8.8;
library ERC165BaseStorage {
struct Layout {
mapping(bytes4 => bool) supportedInterfaces;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.ERC165Base');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
文件 9 的 40:EnumerableSet.sol
pragma solidity ^0.8.8;
library EnumerableSet {
error EnumerableSet__IndexOutOfBounds();
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
struct Bytes32Set {
Set _inner;
}
struct AddressSet {
Set _inner;
}
struct UintSet {
Set _inner;
}
function at(
Bytes32Set storage set,
uint256 index
) internal view returns (bytes32) {
return _at(set._inner, index);
}
function at(
AddressSet storage set,
uint256 index
) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function at(
UintSet storage set,
uint256 index
) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function contains(
Bytes32Set storage set,
bytes32 value
) internal view returns (bool) {
return _contains(set._inner, value);
}
function contains(
AddressSet storage set,
address value
) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function contains(
UintSet storage set,
uint256 value
) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function indexOf(
Bytes32Set storage set,
bytes32 value
) internal view returns (uint256) {
return _indexOf(set._inner, value);
}
function indexOf(
AddressSet storage set,
address value
) internal view returns (uint256) {
return _indexOf(set._inner, bytes32(uint256(uint160(value))));
}
function indexOf(
UintSet storage set,
uint256 value
) internal view returns (uint256) {
return _indexOf(set._inner, bytes32(value));
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function add(
Bytes32Set storage set,
bytes32 value
) internal returns (bool) {
return _add(set._inner, value);
}
function add(
AddressSet storage set,
address value
) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(
Bytes32Set storage set,
bytes32 value
) internal returns (bool) {
return _remove(set._inner, value);
}
function remove(
AddressSet storage set,
address value
) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function remove(
UintSet storage set,
uint256 value
) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function toArray(
Bytes32Set storage set
) internal view returns (bytes32[] memory) {
return set._inner._values;
}
function toArray(
AddressSet storage set
) internal view returns (address[] memory) {
bytes32[] storage values = set._inner._values;
address[] storage array;
assembly {
array.slot := values.slot
}
return array;
}
function toArray(
UintSet storage set
) internal view returns (uint256[] memory) {
bytes32[] storage values = set._inner._values;
uint256[] storage array;
assembly {
array.slot := values.slot
}
return array;
}
function _at(
Set storage set,
uint256 index
) private view returns (bytes32) {
if (index >= set._values.length)
revert EnumerableSet__IndexOutOfBounds();
return set._values[index];
}
function _contains(
Set storage set,
bytes32 value
) private view returns (bool) {
return set._indexes[value] != 0;
}
function _indexOf(
Set storage set,
bytes32 value
) private view returns (uint256) {
unchecked {
return set._indexes[value] - 1;
}
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _add(
Set storage set,
bytes32 value
) private returns (bool status) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
status = true;
}
}
function _remove(
Set storage set,
bytes32 value
) private returns (bool status) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
unchecked {
bytes32 last = set._values[set._values.length - 1];
set._values[valueIndex - 1] = last;
set._indexes[last] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
status = true;
}
}
}
文件 10 的 40:Errors.sol
pragma solidity >=0.8.19;
import { SD1x18 } from "./ValueType.sol";
error PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);
error PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);
error PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);
error PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);
error PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);
error PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);
文件 11 的 40:Helpers.sol
pragma solidity >=0.8.19;
import { wrap } from "./Casting.sol";
import { UD60x18 } from "./ValueType.sol";
function add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(x.unwrap() + y.unwrap());
}
function and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {
result = wrap(x.unwrap() & bits);
}
function and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(x.unwrap() & y.unwrap());
}
function eq(UD60x18 x, UD60x18 y) pure returns (bool result) {
result = x.unwrap() == y.unwrap();
}
function gt(UD60x18 x, UD60x18 y) pure returns (bool result) {
result = x.unwrap() > y.unwrap();
}
function gte(UD60x18 x, UD60x18 y) pure returns (bool result) {
result = x.unwrap() >= y.unwrap();
}
function isZero(UD60x18 x) pure returns (bool result) {
result = x.unwrap() == 0;
}
function lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {
result = wrap(x.unwrap() << bits);
}
function lt(UD60x18 x, UD60x18 y) pure returns (bool result) {
result = x.unwrap() < y.unwrap();
}
function lte(UD60x18 x, UD60x18 y) pure returns (bool result) {
result = x.unwrap() <= y.unwrap();
}
function mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(x.unwrap() % y.unwrap());
}
function neq(UD60x18 x, UD60x18 y) pure returns (bool result) {
result = x.unwrap() != y.unwrap();
}
function not(UD60x18 x) pure returns (UD60x18 result) {
result = wrap(~x.unwrap());
}
function or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(x.unwrap() | y.unwrap());
}
function rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {
result = wrap(x.unwrap() >> bits);
}
function sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(x.unwrap() - y.unwrap());
}
function uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
unchecked {
result = wrap(x.unwrap() + y.unwrap());
}
}
function uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
unchecked {
result = wrap(x.unwrap() - y.unwrap());
}
}
function xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(x.unwrap() ^ y.unwrap());
}
文件 12 的 40:IERC1155.sol
pragma solidity ^0.8.8;
import { IERC165 } from './IERC165.sol';
import { IERC1155Internal } from './IERC1155Internal.sol';
interface IERC1155 is IERC1155Internal, IERC165 {
function balanceOf(
address account,
uint256 id
) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
function isApprovedForAll(
address account,
address operator
) external view returns (bool);
function setApprovalForAll(address operator, bool status) external;
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 13 的 40:IERC1155Base.sol
pragma solidity ^0.8.8;
import { IERC1155 } from '../../../interfaces/IERC1155.sol';
import { IERC1155BaseInternal } from './IERC1155BaseInternal.sol';
interface IERC1155Base is IERC1155BaseInternal, IERC1155 {
}
文件 14 的 40:IERC1155BaseInternal.sol
pragma solidity ^0.8.8;
import { IERC1155Internal } from '../../../interfaces/IERC1155Internal.sol';
interface IERC1155BaseInternal is IERC1155Internal {
error ERC1155Base__ArrayLengthMismatch();
error ERC1155Base__BalanceQueryZeroAddress();
error ERC1155Base__NotOwnerOrApproved();
error ERC1155Base__SelfApproval();
error ERC1155Base__BurnExceedsBalance();
error ERC1155Base__BurnFromZeroAddress();
error ERC1155Base__ERC1155ReceiverRejected();
error ERC1155Base__ERC1155ReceiverNotImplemented();
error ERC1155Base__MintToZeroAddress();
error ERC1155Base__TransferExceedsBalance();
error ERC1155Base__TransferToZeroAddress();
}
文件 15 的 40:IERC1155Enumerable.sol
pragma solidity ^0.8.8;
import { IERC1155BaseInternal } from '../base/IERC1155BaseInternal.sol';
interface IERC1155Enumerable is IERC1155BaseInternal {
function totalSupply(uint256 id) external view returns (uint256);
function totalHolders(uint256 id) external view returns (uint256);
function accountsByToken(
uint256 id
) external view returns (address[] memory);
function tokensByAccount(
address account
) external view returns (uint256[] memory);
}
文件 16 的 40:IERC1155Internal.sol
pragma solidity ^0.8.8;
interface IERC1155Internal {
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 value
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(
address indexed account,
address indexed operator,
bool approved
);
}
文件 17 的 40:IERC165.sol
pragma solidity ^0.8.8;
import { IERC165Internal } from './IERC165Internal.sol';
interface IERC165 is IERC165Internal {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 18 的 40:IERC165BaseInternal.sol
pragma solidity ^0.8.0;
import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';
interface IERC165BaseInternal is IERC165Internal {
error ERC165Base__InvalidInterfaceId();
}
文件 19 的 40:IERC165Internal.sol
pragma solidity ^0.8.8;
interface IERC165Internal {
}
文件 20 的 40:IERC20.sol
pragma solidity ^0.8.8;
import { IERC20Internal } from './IERC20Internal.sol';
interface IERC20 is IERC20Internal {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(
address holder,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function transferFrom(
address holder,
address recipient,
uint256 amount
) external returns (bool);
}
文件 21 的 40:IERC20Internal.sol
pragma solidity ^0.8.8;
interface IERC20Internal {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
文件 22 的 40:IERC20Metadata.sol
pragma solidity ^0.8.8;
import { IERC20MetadataInternal } from './IERC20MetadataInternal.sol';
interface IERC20Metadata is IERC20MetadataInternal {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 23 的 40:IERC20MetadataInternal.sol
pragma solidity ^0.8.8;
interface IERC20MetadataInternal {
}
文件 24 的 40:IOptionPS.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {IERC1155Base} from "@solidstate/contracts/token/ERC1155/base/IERC1155Base.sol";
import {IERC1155Enumerable} from "@solidstate/contracts/token/ERC1155/enumerable/IERC1155Enumerable.sol";
interface IOptionPS is IERC1155Base, IERC1155Enumerable {
enum TokenType {
Long,
Short
}
error OptionPS__ExercisePeriodEnded(uint256 maturity, uint256 exercisePeriodEnd);
error OptionPS__ExercisePeriodNotEnded(uint256 maturity, uint256 exercisePeriodEnd);
error OptionPS__OptionMaturityNot8UTC(uint256 maturity);
error OptionPS__OptionExpired(uint256 maturity);
error OptionPS__OptionNotExpired(uint256 maturity);
error OptionPS__StrikeNotMultipleOfStrikeInterval(UD60x18 strike, UD60x18 strikeInterval);
event Exercise(
address indexed user,
UD60x18 strike,
uint256 maturity,
UD60x18 contractSize,
UD60x18 exerciseValue,
UD60x18 exerciseCost,
UD60x18 exerciseFee
);
event Settle(
address indexed user,
UD60x18 contractSize,
UD60x18 strike,
uint256 maturity,
UD60x18 collateralAmount,
UD60x18 exerciseTokenAmount
);
event Underwrite(
address indexed underwriter,
address indexed longReceiver,
UD60x18 strike,
uint256 maturity,
UD60x18 contractSize
);
event Annihilate(address indexed annihilator, UD60x18 strike, uint256 maturity, UD60x18 contractSize);
function getSettings() external view returns (address base, address quote, bool isCall);
function getExerciseDuration() external pure returns (uint256);
function underwrite(UD60x18 strike, uint64 maturity, address longReceiver, UD60x18 contractSize) external;
function annihilate(UD60x18 strike, uint64 maturity, UD60x18 contractSize) external;
function exercise(UD60x18 strike, uint64 maturity, UD60x18 contractSize) external returns (uint256 exerciseValue);
function settle(
UD60x18 strike,
uint64 maturity,
UD60x18 contractSize
) external returns (uint256 collateralAmount, uint256 exerciseTokenAmount);
function getTokenIds() external view returns (uint256[] memory);
}
文件 25 的 40:IProxy.sol
pragma solidity ^0.8.8;
interface IProxy {
error Proxy__ImplementationIsNotContract();
fallback() external payable;
}
文件 26 的 40:IProxyManager.sol
pragma solidity ^0.8.19;
interface IProxyManager {
event ManagedImplementationSet(address implementation);
function getManagedProxyImplementation() external view returns (address);
function setManagedProxyImplementation(address implementation) external;
}
文件 27 的 40:Math.sol
pragma solidity >=0.8.19;
import "../Common.sol" as Common;
import "./Errors.sol" as Errors;
import { wrap } from "./Casting.sol";
import {
uEXP_MAX_INPUT,
uEXP2_MAX_INPUT,
uHALF_UNIT,
uLOG2_10,
uLOG2_E,
uMAX_UD60x18,
uMAX_WHOLE_UD60x18,
UNIT,
uUNIT,
uUNIT_SQUARED,
ZERO
} from "./Constants.sol";
import { UD60x18 } from "./ValueType.sol";
function avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
unchecked {
result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));
}
}
function ceil(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint > uMAX_WHOLE_UD60x18) {
revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);
}
assembly ("memory-safe") {
let remainder := mod(x, uUNIT)
let delta := sub(uUNIT, remainder)
result := add(x, mul(delta, gt(remainder, 0)))
}
}
function div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));
}
function exp(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint > uEXP_MAX_INPUT) {
revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);
}
unchecked {
uint256 doubleUnitProduct = xUint * uLOG2_E;
result = exp2(wrap(doubleUnitProduct / uUNIT));
}
}
function exp2(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint > uEXP2_MAX_INPUT) {
revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);
}
uint256 x_192x64 = (xUint << 64) / uUNIT;
result = wrap(Common.exp2(x_192x64));
}
function floor(UD60x18 x) pure returns (UD60x18 result) {
assembly ("memory-safe") {
let remainder := mod(x, uUNIT)
result := sub(x, mul(remainder, gt(remainder, 0)))
}
}
function frac(UD60x18 x) pure returns (UD60x18 result) {
assembly ("memory-safe") {
result := mod(x, uUNIT)
}
}
function gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
if (xUint == 0 || yUint == 0) {
return ZERO;
}
unchecked {
uint256 xyUint = xUint * yUint;
if (xyUint / xUint != yUint) {
revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);
}
result = wrap(Common.sqrt(xyUint));
}
}
function inv(UD60x18 x) pure returns (UD60x18 result) {
unchecked {
result = wrap(uUNIT_SQUARED / x.unwrap());
}
}
function ln(UD60x18 x) pure returns (UD60x18 result) {
unchecked {
result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);
}
}
function log10(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint < uUNIT) {
revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);
}
assembly ("memory-safe") {
switch x
case 1 { result := mul(uUNIT, sub(0, 18)) }
case 10 { result := mul(uUNIT, sub(1, 18)) }
case 100 { result := mul(uUNIT, sub(2, 18)) }
case 1000 { result := mul(uUNIT, sub(3, 18)) }
case 10000 { result := mul(uUNIT, sub(4, 18)) }
case 100000 { result := mul(uUNIT, sub(5, 18)) }
case 1000000 { result := mul(uUNIT, sub(6, 18)) }
case 10000000 { result := mul(uUNIT, sub(7, 18)) }
case 100000000 { result := mul(uUNIT, sub(8, 18)) }
case 1000000000 { result := mul(uUNIT, sub(9, 18)) }
case 10000000000 { result := mul(uUNIT, sub(10, 18)) }
case 100000000000 { result := mul(uUNIT, sub(11, 18)) }
case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }
case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }
case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }
case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }
case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }
case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }
case 1000000000000000000 { result := 0 }
case 10000000000000000000 { result := uUNIT }
case 100000000000000000000 { result := mul(uUNIT, 2) }
case 1000000000000000000000 { result := mul(uUNIT, 3) }
case 10000000000000000000000 { result := mul(uUNIT, 4) }
case 100000000000000000000000 { result := mul(uUNIT, 5) }
case 1000000000000000000000000 { result := mul(uUNIT, 6) }
case 10000000000000000000000000 { result := mul(uUNIT, 7) }
case 100000000000000000000000000 { result := mul(uUNIT, 8) }
case 1000000000000000000000000000 { result := mul(uUNIT, 9) }
case 10000000000000000000000000000 { result := mul(uUNIT, 10) }
case 100000000000000000000000000000 { result := mul(uUNIT, 11) }
case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }
case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }
case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }
case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }
case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }
case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }
case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }
case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }
case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }
case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }
case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }
case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }
case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }
case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }
case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }
case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }
case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }
case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }
case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }
case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }
case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }
case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }
case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }
case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }
case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }
case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }
case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }
case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }
case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }
case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }
case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }
case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }
case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }
case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }
case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }
case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }
case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }
case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }
case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }
case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }
case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }
case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }
case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }
case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }
case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }
case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }
case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }
case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }
default { result := uMAX_UD60x18 }
}
if (result.unwrap() == uMAX_UD60x18) {
unchecked {
result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);
}
}
}
function log2(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint < uUNIT) {
revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);
}
unchecked {
uint256 n = Common.msb(xUint / uUNIT);
uint256 resultUint = n * uUNIT;
uint256 y = xUint >> n;
if (y == uUNIT) {
return wrap(resultUint);
}
uint256 DOUBLE_UNIT = 2e18;
for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {
y = (y * y) / uUNIT;
if (y >= DOUBLE_UNIT) {
resultUint += delta;
y >>= 1;
}
}
result = wrap(resultUint);
}
}
function mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));
}
function pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
if (xUint == 0) {
return yUint == 0 ? UNIT : ZERO;
}
else if (xUint == uUNIT) {
return UNIT;
}
if (yUint == 0) {
return UNIT;
}
else if (yUint == uUNIT) {
return x;
}
if (xUint > uUNIT) {
result = exp2(mul(log2(x), y));
}
else {
UD60x18 i = wrap(uUNIT_SQUARED / xUint);
UD60x18 w = exp2(mul(log2(i), y));
result = wrap(uUNIT_SQUARED / w.unwrap());
}
}
function powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;
for (y >>= 1; y > 0; y >>= 1) {
xUint = Common.mulDiv18(xUint, xUint);
if (y & 1 > 0) {
resultUint = Common.mulDiv18(resultUint, xUint);
}
}
result = wrap(resultUint);
}
function sqrt(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
unchecked {
if (xUint > uMAX_UD60x18 / uUNIT) {
revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);
}
result = wrap(Common.sqrt(xUint * uUNIT));
}
}
文件 28 的 40:OptionMath.sol
pragma solidity ^0.8.19;
import {BokkyPooBahsDateTimeLibrary as DateTime} from "lib/BokkyPooBahsDateTimeLibrary/contracts/BokkyPooBahsDateTimeLibrary.sol";
import {UD60x18, ud} from "lib/prb-math/src/UD60x18.sol";
import {SD59x18} from "lib/prb-math/src/SD59x18.sol";
import {ZERO, ONE, TWO, iZERO, iONE, iTWO, iFOUR, iNINE} from "./Constants.sol";
library OptionMath {
struct BlackScholesPriceVarsInternal {
int256 discountFactor;
int256 timeScaledVol;
int256 timeScaledVar;
int256 timeScaledRiskFreeRate;
}
UD60x18 internal constant INITIALIZATION_ALPHA = UD60x18.wrap(5e18);
UD60x18 internal constant ATM_MONEYNESS = UD60x18.wrap(0.5e18);
uint256 internal constant NEAR_TERM_TTM = 14 days;
uint256 internal constant ONE_YEAR_TTM = 365 days;
UD60x18 internal constant FEE_SCALAR = UD60x18.wrap(100e18);
SD59x18 internal constant ALPHA = SD59x18.wrap(-6.37309208e18);
SD59x18 internal constant LAMBDA = SD59x18.wrap(-0.61228883e18);
SD59x18 internal constant S1 = SD59x18.wrap(-0.11105481e18);
SD59x18 internal constant S2 = SD59x18.wrap(0.44334159e18);
int256 internal constant SQRT_2PI = 2_506628274631000502;
UD60x18 internal constant MIN_INPUT_PRICE = UD60x18.wrap(1e1);
UD60x18 internal constant MAX_INPUT_PRICE = UD60x18.wrap(1e34);
error OptionMath__NonPositiveVol();
error OptionMath__OutOfBoundsPrice(UD60x18 min, UD60x18 max, UD60x18 price);
error OptionMath__Underflow();
function helperNormal(SD59x18 x) internal pure returns (SD59x18 result) {
SD59x18 a = (ALPHA / LAMBDA) * S1;
SD59x18 b = (S1 * x + iONE).pow(LAMBDA / S1) - iONE;
result = ((a * b + S2 * x).exp() * (-iTWO.ln())).exp();
}
function normalCdf(SD59x18 x) internal pure returns (SD59x18 result) {
if (x <= -iNINE) {
result = iZERO;
} else if (x >= iNINE) {
result = iONE;
} else {
result = ((iONE + helperNormal(-x)) - helperNormal(x)) / iTWO;
}
}
function normalPdf(SD59x18 x) internal pure returns (SD59x18 z) {
SD59x18 e;
int256 one = iONE.unwrap();
uint256 two = TWO.unwrap();
assembly {
e := sdiv(mul(add(not(x), 1), x), two)
}
e = e.exp();
assembly {
z := sdiv(mul(e, one), SQRT_2PI)
}
}
function relu(SD59x18 x) internal pure returns (UD60x18) {
if (x >= iZERO) {
return x.intoUD60x18();
}
return ZERO;
}
function d1d2(
UD60x18 spot,
UD60x18 strike,
UD60x18 timeToMaturity,
UD60x18 volAnnualized,
UD60x18 riskFreeRate
) internal pure returns (SD59x18 d1, SD59x18 d2) {
UD60x18 timeScaledRiskFreeRate = riskFreeRate * timeToMaturity;
UD60x18 timeScaledVariance = (volAnnualized.powu(2) / TWO) * timeToMaturity;
UD60x18 timeScaledStd = volAnnualized * timeToMaturity.sqrt();
SD59x18 lnSpot = (spot / strike).intoSD59x18().ln();
d1 =
(lnSpot + timeScaledVariance.intoSD59x18() + timeScaledRiskFreeRate.intoSD59x18()) /
timeScaledStd.intoSD59x18();
d2 = d1 - timeScaledStd.intoSD59x18();
}
function optionDelta(
UD60x18 spot,
UD60x18 strike,
UD60x18 timeToMaturity,
UD60x18 volAnnualized,
UD60x18 riskFreeRate,
bool isCall
) internal pure returns (SD59x18) {
(SD59x18 d1, ) = d1d2(spot, strike, timeToMaturity, volAnnualized, riskFreeRate);
if (isCall) {
return normalCdf(d1);
} else {
return -normalCdf(-d1);
}
}
function blackScholesPrice(
UD60x18 spot,
UD60x18 strike,
UD60x18 timeToMaturity,
UD60x18 volAnnualized,
UD60x18 riskFreeRate,
bool isCall
) internal pure returns (UD60x18) {
SD59x18 _spot = spot.intoSD59x18();
SD59x18 _strike = strike.intoSD59x18();
if (volAnnualized == ZERO) revert OptionMath__NonPositiveVol();
if (timeToMaturity == ZERO) {
if (isCall) {
return relu(_spot - _strike);
}
return relu(_strike - _spot);
}
SD59x18 discountFactor;
if (riskFreeRate > ZERO) {
discountFactor = (riskFreeRate * timeToMaturity).intoSD59x18().exp();
} else {
discountFactor = iONE;
}
(SD59x18 d1, SD59x18 d2) = d1d2(spot, strike, timeToMaturity, volAnnualized, riskFreeRate);
SD59x18 sign = isCall ? iONE : -iONE;
SD59x18 a = (_spot / _strike) * normalCdf(d1 * sign);
SD59x18 b = normalCdf(d2 * sign) / discountFactor;
SD59x18 scaledPrice = (a - b) * sign;
if (scaledPrice < SD59x18.wrap(-1e12)) revert OptionMath__Underflow();
if (scaledPrice >= SD59x18.wrap(-1e12) && scaledPrice <= iZERO) scaledPrice = iZERO;
return (scaledPrice * _strike).intoUD60x18();
}
function is8AMUTC(uint256 maturity) internal pure returns (bool) {
return maturity % 24 hours == 8 hours;
}
function isFriday(uint256 maturity) internal pure returns (bool) {
return DateTime.getDayOfWeek(maturity) == DateTime.DOW_FRI;
}
function isLastFriday(uint256 maturity) internal pure returns (bool) {
uint256 dayOfMonth = DateTime.getDay(maturity);
uint256 lastDayOfMonth = DateTime.getDaysInMonth(maturity);
if (lastDayOfMonth - dayOfMonth >= 7) return false;
return isFriday(maturity);
}
function calculateTimeToMaturity(uint256 maturity) internal view returns (uint256) {
return maturity - block.timestamp;
}
function calculateStrikeInterval(UD60x18 strike) internal pure returns (UD60x18) {
if (strike < MIN_INPUT_PRICE || strike > MAX_INPUT_PRICE)
revert OptionMath__OutOfBoundsPrice(MIN_INPUT_PRICE, MAX_INPUT_PRICE, strike);
uint256 _strike = strike.unwrap();
uint256 exponent = log10Floor(_strike);
uint256 multiplier = (_strike >= 5 * 10 ** exponent) ? 5 : 1;
return ud(multiplier * 10 ** (exponent - 1));
}
function roundToStrikeInterval(UD60x18 strike) internal pure returns (UD60x18) {
uint256 _strike = strike.div(ONE).unwrap();
uint256 interval = calculateStrikeInterval(strike).div(ONE).unwrap();
uint256 lower = interval * (_strike / interval);
uint256 upper = interval * ((_strike / interval) + 1);
return (_strike - lower < upper - _strike) ? ud(lower) : ud(upper);
}
function logMoneyness(UD60x18 spot, UD60x18 strike) internal pure returns (UD60x18) {
return (spot / strike).intoSD59x18().ln().abs().intoUD60x18();
}
function initializationFee(UD60x18 spot, UD60x18 strike, uint256 maturity) internal view returns (UD60x18) {
UD60x18 moneyness = logMoneyness(spot, strike);
uint256 timeToMaturity = calculateTimeToMaturity(maturity);
UD60x18 kBase = moneyness < ATM_MONEYNESS
? (ATM_MONEYNESS - moneyness).intoSD59x18().pow(iFOUR).intoUD60x18()
: moneyness - ATM_MONEYNESS;
uint256 tBase = timeToMaturity < NEAR_TERM_TTM
? 3 * (NEAR_TERM_TTM - timeToMaturity) + NEAR_TERM_TTM
: timeToMaturity;
UD60x18 scaledT = (ud(tBase * 1e18) / ud(ONE_YEAR_TTM * 1e18)).sqrt();
return INITIALIZATION_ALPHA * (kBase + scaledT) * scaledT * FEE_SCALAR;
}
function scaleDecimals(uint256 value, uint8 inputDecimals, uint8 targetDecimals) internal pure returns (uint256) {
if (targetDecimals == inputDecimals) return value;
if (targetDecimals > inputDecimals) return value * (10 ** (targetDecimals - inputDecimals));
return value / (10 ** (inputDecimals - targetDecimals));
}
function scaleDecimals(int256 value, uint8 inputDecimals, uint8 targetDecimals) internal pure returns (int256) {
if (targetDecimals == inputDecimals) return value;
if (targetDecimals > inputDecimals) return value * int256(10 ** (targetDecimals - inputDecimals));
return value / int256(10 ** (inputDecimals - targetDecimals));
}
function log10Floor(uint256 input) internal pure returns (uint256 count) {
while (input >= 10) {
input /= 10;
count++;
}
return count;
}
}
文件 29 的 40:OptionPSProxy.sol
pragma solidity ^0.8.19;
import {OwnableStorage} from "@solidstate/contracts/access/ownable/OwnableStorage.sol";
import {IERC1155} from "@solidstate/contracts/interfaces/IERC1155.sol";
import {IERC165} from "@solidstate/contracts/interfaces/IERC165.sol";
import {ERC165BaseInternal} from "@solidstate/contracts/introspection/ERC165/base/ERC165BaseInternal.sol";
import {Proxy} from "@solidstate/contracts/proxy/Proxy.sol";
import {IERC20Metadata} from "@solidstate/contracts/token/ERC20/metadata/IERC20Metadata.sol";
import {IProxyManager} from "../../proxy/IProxyManager.sol";
import {OptionPSStorage} from "./OptionPSStorage.sol";
contract OptionPSProxy is Proxy, ERC165BaseInternal {
IProxyManager private immutable MANAGER;
constructor(IProxyManager manager, address base, address quote, bool isCall) {
MANAGER = manager;
OwnableStorage.layout().owner = msg.sender;
OptionPSStorage.Layout storage l = OptionPSStorage.layout();
l.isCall = isCall;
l.baseDecimals = IERC20Metadata(base).decimals();
l.quoteDecimals = IERC20Metadata(quote).decimals();
l.base = base;
l.quote = quote;
_setSupportsInterface(type(IERC165).interfaceId, true);
_setSupportsInterface(type(IERC1155).interfaceId, true);
}
function _getImplementation() internal view override returns (address) {
return MANAGER.getManagedProxyImplementation();
}
receive() external payable {}
}
文件 30 的 40:OptionPSStorage.sol
pragma solidity ^0.8.19;
import {UD60x18, ud} from "lib/prb-math/src/UD60x18.sol";
import {IERC20} from "@solidstate/contracts/interfaces/IERC20.sol";
import {SafeCast} from "@solidstate/contracts/utils/SafeCast.sol";
import {SafeERC20} from "@solidstate/contracts/utils/SafeERC20.sol";
import {EnumerableSet} from "@solidstate/contracts/data/EnumerableSet.sol";
import {OptionMath} from "../../libraries/OptionMath.sol";
import {IOptionPS} from "./IOptionPS.sol";
library OptionPSStorage {
using SafeCast for int256;
using SafeCast for uint256;
using SafeERC20 for IERC20;
bytes32 internal constant STORAGE_SLOT = keccak256("premia.contracts.storage.OptionPS");
struct Layout {
bool isCall;
uint8 baseDecimals;
uint8 quoteDecimals;
address base;
address quote;
mapping(UD60x18 strike => mapping(uint64 maturity => UD60x18 amount)) totalUnderwritten;
mapping(UD60x18 strike => mapping(uint64 maturity => UD60x18 amount)) totalExercised;
EnumerableSet.UintSet tokenIds;
}
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
function formatTokenId(
IOptionPS.TokenType tokenType,
uint64 maturity,
UD60x18 strike
) internal pure returns (uint256 tokenId) {
tokenId =
(uint256(tokenType) << 248) +
(uint256(maturity) << 128) +
uint256(int256(fromUD60x18ToInt128(strike)));
}
function parseTokenId(
uint256 tokenId
) internal pure returns (IOptionPS.TokenType tokenType, uint64 maturity, int128 strike) {
assembly {
tokenType := shr(248, tokenId)
maturity := shr(128, tokenId)
strike := tokenId
}
}
function getCollateral(Layout storage l) internal view returns (address) {
return l.isCall ? l.base : l.quote;
}
function getExerciseToken(Layout storage l) internal view returns (address) {
return l.isCall ? l.quote : l.base;
}
function toTokenDecimals(Layout storage l, UD60x18 value, address token) internal view returns (uint256) {
uint8 decimals = token == l.base ? l.baseDecimals : l.quoteDecimals;
return OptionMath.scaleDecimals(value.unwrap(), 18, decimals);
}
function fromTokenDecimals(Layout storage l, uint256 value, address token) internal view returns (UD60x18) {
uint8 decimals = token == l.base ? l.baseDecimals : l.quoteDecimals;
return ud(OptionMath.scaleDecimals(value, decimals, 18));
}
function fromUD60x18ToInt128(UD60x18 u) internal pure returns (int128) {
return u.unwrap().toInt256().toInt128();
}
}
文件 31 的 40:OwnableStorage.sol
pragma solidity ^0.8.8;
library OwnableStorage {
struct Layout {
address owner;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.Ownable');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
文件 32 的 40:Proxy.sol
pragma solidity ^0.8.8;
import { AddressUtils } from '../utils/AddressUtils.sol';
import { IProxy } from './IProxy.sol';
abstract contract Proxy is IProxy {
using AddressUtils for address;
fallback() external payable virtual {
address implementation = _getImplementation();
if (!implementation.isContract())
revert Proxy__ImplementationIsNotContract();
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(
gas(),
implementation,
0,
calldatasize(),
0,
0
)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
function _getImplementation() internal virtual returns (address);
}
文件 33 的 40:SD49x28.sol
pragma solidity ^0.8.19;
import {mulDiv} from "lib/prb-math/src/Common.sol";
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {SD59x18} from "lib/prb-math/src/SD59x18.sol";
import {UD50x28} from "./UD50x28.sol";
type SD49x28 is int256;
int256 constant uMAX_SD49x28 = type(int256).max;
int256 constant uMIN_SD49x28 = type(int256).min;
int256 constant uUNIT = 1e28;
SD49x28 constant UNIT = SD49x28.wrap(uUNIT);
int256 constant SCALING_FACTOR = 1e10;
error SD49x28_Mul_InputTooSmall();
error SD49x28_Mul_Overflow(SD49x28 x, SD49x28 y);
error SD49x28_Div_InputTooSmall();
error SD49x28_Div_Overflow(SD49x28 x, SD49x28 y);
error SD49x28_IntoUD50x28_Underflow(SD49x28 x);
error SD49x28_Abs_MinSD49x28();
function wrap(int256 x) pure returns (SD49x28 result) {
result = SD49x28.wrap(x);
}
function unwrap(SD49x28 x) pure returns (int256 result) {
result = SD49x28.unwrap(x);
}
function sd49x28(int256 x) pure returns (SD49x28 result) {
result = SD49x28.wrap(x);
}
function intoUD50x28(SD49x28 x) pure returns (UD50x28 result) {
int256 xInt = SD49x28.unwrap(x);
if (xInt < 0) {
revert SD49x28_IntoUD50x28_Underflow(x);
}
result = UD50x28.wrap(uint256(xInt));
}
function intoUD60x18(SD49x28 x) pure returns (UD60x18 result) {
return intoUD50x28(x).intoUD60x18();
}
function intoSD59x18(SD49x28 x) pure returns (SD59x18 result) {
result = SD59x18.wrap(x.unwrap() / SCALING_FACTOR);
}
function add(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
return wrap(x.unwrap() + y.unwrap());
}
function and(SD49x28 x, int256 bits) pure returns (SD49x28 result) {
return wrap(x.unwrap() & bits);
}
function and2(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
return wrap(x.unwrap() & y.unwrap());
}
function eq(SD49x28 x, SD49x28 y) pure returns (bool result) {
result = x.unwrap() == y.unwrap();
}
function gt(SD49x28 x, SD49x28 y) pure returns (bool result) {
result = x.unwrap() > y.unwrap();
}
function gte(SD49x28 x, SD49x28 y) pure returns (bool result) {
result = x.unwrap() >= y.unwrap();
}
function isZero(SD49x28 x) pure returns (bool result) {
result = x.unwrap() == 0;
}
function lshift(SD49x28 x, uint256 bits) pure returns (SD49x28 result) {
result = wrap(x.unwrap() << bits);
}
function lt(SD49x28 x, SD49x28 y) pure returns (bool result) {
result = x.unwrap() < y.unwrap();
}
function lte(SD49x28 x, SD49x28 y) pure returns (bool result) {
result = x.unwrap() <= y.unwrap();
}
function mod(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
result = wrap(x.unwrap() % y.unwrap());
}
function neq(SD49x28 x, SD49x28 y) pure returns (bool result) {
result = x.unwrap() != y.unwrap();
}
function not(SD49x28 x) pure returns (SD49x28 result) {
result = wrap(~x.unwrap());
}
function or(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
result = wrap(x.unwrap() | y.unwrap());
}
function rshift(SD49x28 x, uint256 bits) pure returns (SD49x28 result) {
result = wrap(x.unwrap() >> bits);
}
function sub(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
result = wrap(x.unwrap() - y.unwrap());
}
function unary(SD49x28 x) pure returns (SD49x28 result) {
result = wrap(-x.unwrap());
}
function uncheckedAdd(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
unchecked {
result = wrap(x.unwrap() + y.unwrap());
}
}
function uncheckedSub(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
unchecked {
result = wrap(x.unwrap() - y.unwrap());
}
}
function uncheckedUnary(SD49x28 x) pure returns (SD49x28 result) {
unchecked {
result = wrap(-x.unwrap());
}
}
function xor(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
result = wrap(x.unwrap() ^ y.unwrap());
}
function abs(SD49x28 x) pure returns (SD49x28 result) {
int256 xInt = x.unwrap();
if (xInt == uMIN_SD49x28) {
revert SD49x28_Abs_MinSD49x28();
}
result = xInt < 0 ? wrap(-xInt) : x;
}
function avg(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
int256 xInt = x.unwrap();
int256 yInt = y.unwrap();
unchecked {
int256 sum = (xInt >> 1) + (yInt >> 1);
if (sum < 0) {
assembly ("memory-safe") {
result := add(sum, and(or(xInt, yInt), 1))
}
} else {
result = wrap(sum + (xInt & yInt & 1));
}
}
}
function div(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
int256 xInt = x.unwrap();
int256 yInt = y.unwrap();
if (xInt == uMIN_SD49x28 || yInt == uMIN_SD49x28) {
revert SD49x28_Div_InputTooSmall();
}
uint256 xAbs;
uint256 yAbs;
unchecked {
xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);
yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);
}
uint256 resultAbs = mulDiv(xAbs, uint256(uUNIT), yAbs);
if (resultAbs > uint256(uMAX_SD49x28)) {
revert SD49x28_Div_Overflow(x, y);
}
bool sameSign = (xInt ^ yInt) > -1;
unchecked {
result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));
}
}
function mul(SD49x28 x, SD49x28 y) pure returns (SD49x28 result) {
int256 xInt = x.unwrap();
int256 yInt = y.unwrap();
if (xInt == uMIN_SD49x28 || yInt == uMIN_SD49x28) {
revert SD49x28_Mul_InputTooSmall();
}
uint256 xAbs;
uint256 yAbs;
unchecked {
xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);
yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);
}
uint256 resultAbs = mulDiv(xAbs, yAbs, uint256(uUNIT));
if (resultAbs > uint256(uMAX_SD49x28)) {
revert SD49x28_Mul_Overflow(x, y);
}
bool sameSign = (xInt ^ yInt) > -1;
unchecked {
result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));
}
}
using {
unwrap,
intoSD59x18,
intoUD50x28,
intoUD60x18,
abs,
avg,
add,
and,
eq,
gt,
gte,
isZero,
lshift,
lt,
lte,
mod,
neq,
not,
or,
rshift,
sub,
uncheckedAdd,
uncheckedSub,
xor
} for SD49x28 global;
using {
add as +,
and2 as &,
div as /,
eq as ==,
gt as >,
gte as >=,
lt as <,
lte as <=,
or as |,
mod as %,
mul as *,
neq as !=,
not as ~,
sub as -,
unary as -,
xor as ^
} for SD49x28 global;
文件 34 的 40:SD59x18.sol
pragma solidity >=0.8.19;
import "./sd59x18/Casting.sol";
import "./sd59x18/Constants.sol";
import "./sd59x18/Conversions.sol";
import "./sd59x18/Errors.sol";
import "./sd59x18/Helpers.sol";
import "./sd59x18/Math.sol";
import "./sd59x18/ValueType.sol";
文件 35 的 40:SafeCast.sol
pragma solidity ^0.8.8;
library SafeCast {
error SafeCast__NegativeValue();
error SafeCast__ValueDoesNotFit();
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) revert SafeCast__ValueDoesNotFit();
return uint224(value);
}
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) revert SafeCast__ValueDoesNotFit();
return uint128(value);
}
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) revert SafeCast__ValueDoesNotFit();
return uint96(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) revert SafeCast__ValueDoesNotFit();
return uint64(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) revert SafeCast__ValueDoesNotFit();
return uint32(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) revert SafeCast__ValueDoesNotFit();
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) revert SafeCast__ValueDoesNotFit();
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) revert SafeCast__NegativeValue();
return uint256(value);
}
function toInt128(int256 value) internal pure returns (int128) {
if (value < type(int128).min || value > type(int128).max)
revert SafeCast__ValueDoesNotFit();
return int128(value);
}
function toInt64(int256 value) internal pure returns (int64) {
if (value < type(int64).min || value > type(int64).max)
revert SafeCast__ValueDoesNotFit();
return int64(value);
}
function toInt32(int256 value) internal pure returns (int32) {
if (value < type(int32).min || value > type(int32).max)
revert SafeCast__ValueDoesNotFit();
return int32(value);
}
function toInt16(int256 value) internal pure returns (int16) {
if (value < type(int16).min || value > type(int16).max)
revert SafeCast__ValueDoesNotFit();
return int16(value);
}
function toInt8(int256 value) internal pure returns (int8) {
if (value < type(int8).min || value > type(int8).max)
revert SafeCast__ValueDoesNotFit();
return int8(value);
}
function toInt256(uint256 value) internal pure returns (int256) {
if (value > uint256(type(int256).max))
revert SafeCast__ValueDoesNotFit();
return int256(value);
}
}
文件 36 的 40:SafeERC20.sol
pragma solidity ^0.8.8;
import { IERC20 } from '../interfaces/IERC20.sol';
import { AddressUtils } from './AddressUtils.sol';
library SafeERC20 {
using AddressUtils for address;
error SafeERC20__ApproveFromNonZeroToNonZero();
error SafeERC20__DecreaseAllowanceBelowZero();
error SafeERC20__OperationFailed();
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transfer.selector, to, value)
);
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
);
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
if ((value != 0) && (token.allowance(address(this), spender) != 0))
revert SafeERC20__ApproveFromNonZeroToNonZero();
_callOptionalReturn(
token,
abi.encodeWithSelector(token.approve.selector, spender, value)
);
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
newAllowance
)
);
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
if (oldAllowance < value)
revert SafeERC20__DecreaseAllowanceBelowZero();
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
newAllowance
)
);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(
data,
'SafeERC20: low-level call failed'
);
if (returndata.length > 0) {
if (!abi.decode(returndata, (bool)))
revert SafeERC20__OperationFailed();
}
}
}
文件 37 的 40:UD50x28.sol
pragma solidity ^0.8.19;
import {mulDiv} from "lib/prb-math/src/Common.sol";
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {SD49x28, uMAX_SD49x28} from "./SD49x28.sol";
type UD50x28 is uint256;
uint256 constant uMAX_UD50x28 = type(uint256).max;
uint256 constant uUNIT = 1e28;
UD50x28 constant UNIT = UD50x28.wrap(uUNIT);
uint256 constant SCALING_FACTOR = 1e10;
error UD50x28_IntoSD49x28_Overflow(UD50x28 x);
function wrap(uint256 x) pure returns (UD50x28 result) {
result = UD50x28.wrap(x);
}
function unwrap(UD50x28 x) pure returns (uint256 result) {
result = UD50x28.unwrap(x);
}
function ud50x28(uint256 x) pure returns (UD50x28 result) {
result = UD50x28.wrap(x);
}
function intoSD49x28(UD50x28 x) pure returns (SD49x28 result) {
uint256 xUint = UD50x28.unwrap(x);
if (xUint > uint256(uMAX_SD49x28)) {
revert UD50x28_IntoSD49x28_Overflow(x);
}
result = SD49x28.wrap(int256(xUint));
}
function intoUD60x18(UD50x28 x) pure returns (UD60x18 result) {
result = UD60x18.wrap(x.unwrap() / SCALING_FACTOR);
}
function add(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = wrap(x.unwrap() + y.unwrap());
}
function and(UD50x28 x, uint256 bits) pure returns (UD50x28 result) {
result = wrap(x.unwrap() & bits);
}
function and2(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = wrap(x.unwrap() & y.unwrap());
}
function eq(UD50x28 x, UD50x28 y) pure returns (bool result) {
result = x.unwrap() == y.unwrap();
}
function gt(UD50x28 x, UD50x28 y) pure returns (bool result) {
result = x.unwrap() > y.unwrap();
}
function gte(UD50x28 x, UD50x28 y) pure returns (bool result) {
result = x.unwrap() >= y.unwrap();
}
function isZero(UD50x28 x) pure returns (bool result) {
result = x.unwrap() == 0;
}
function lshift(UD50x28 x, uint256 bits) pure returns (UD50x28 result) {
result = wrap(x.unwrap() << bits);
}
function lt(UD50x28 x, UD50x28 y) pure returns (bool result) {
result = x.unwrap() < y.unwrap();
}
function lte(UD50x28 x, UD50x28 y) pure returns (bool result) {
result = x.unwrap() <= y.unwrap();
}
function mod(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = wrap(x.unwrap() % y.unwrap());
}
function neq(UD50x28 x, UD50x28 y) pure returns (bool result) {
result = x.unwrap() != y.unwrap();
}
function not(UD50x28 x) pure returns (UD50x28 result) {
result = wrap(~x.unwrap());
}
function or(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = wrap(x.unwrap() | y.unwrap());
}
function rshift(UD50x28 x, uint256 bits) pure returns (UD50x28 result) {
result = wrap(x.unwrap() >> bits);
}
function sub(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = wrap(x.unwrap() - y.unwrap());
}
function uncheckedAdd(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
unchecked {
result = wrap(x.unwrap() + y.unwrap());
}
}
function uncheckedSub(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
unchecked {
result = wrap(x.unwrap() - y.unwrap());
}
}
function xor(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = wrap(x.unwrap() ^ y.unwrap());
}
function avg(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
unchecked {
result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));
}
}
function div(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = UD50x28.wrap(mulDiv(x.unwrap(), uUNIT, y.unwrap()));
}
function mul(UD50x28 x, UD50x28 y) pure returns (UD50x28 result) {
result = UD50x28.wrap(mulDiv(x.unwrap(), y.unwrap(), uUNIT));
}
using {
unwrap,
intoUD60x18,
intoSD49x28,
avg,
add,
and,
eq,
gt,
gte,
isZero,
lshift,
lt,
lte,
mod,
neq,
not,
or,
rshift,
sub,
uncheckedAdd,
uncheckedSub,
xor
} for UD50x28 global;
using {
add as +,
and2 as &,
div as /,
eq as ==,
gt as >,
gte as >=,
lt as <,
lte as <=,
or as |,
mod as %,
mul as *,
neq as !=,
not as ~,
sub as -,
xor as ^
} for UD50x28 global;
文件 38 的 40:UD60x18.sol
pragma solidity >=0.8.19;
import "./ud60x18/Casting.sol";
import "./ud60x18/Constants.sol";
import "./ud60x18/Conversions.sol";
import "./ud60x18/Errors.sol";
import "./ud60x18/Helpers.sol";
import "./ud60x18/Math.sol";
import "./ud60x18/ValueType.sol";
文件 39 的 40:UintUtils.sol
pragma solidity ^0.8.8;
library UintUtils {
error UintUtils__InsufficientHexLength();
bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';
function add(uint256 a, int256 b) internal pure returns (uint256) {
return b < 0 ? sub(a, -b) : a + uint256(b);
}
function sub(uint256 a, int256 b) internal pure returns (uint256) {
return b < 0 ? add(a, -b) : a - uint256(b);
}
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return '0';
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return '0x00';
}
uint256 length = 0;
for (uint256 temp = value; temp != 0; temp >>= 8) {
unchecked {
length++;
}
}
return toHexString(value, length);
}
function toHexString(
uint256 value,
uint256 length
) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = '0';
buffer[1] = 'x';
unchecked {
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
}
if (value != 0) revert UintUtils__InsufficientHexLength();
return string(buffer);
}
}
文件 40 的 40:ValueType.sol
pragma solidity >=0.8.19;
import "./Casting.sol" as Casting;
type UD2x18 is uint64;
using {
Casting.intoSD1x18,
Casting.intoSD59x18,
Casting.intoUD60x18,
Casting.intoUint256,
Casting.intoUint128,
Casting.intoUint40,
Casting.unwrap
} for UD2x18 global;
{
"compilationTarget": {
"contracts/mining/optionPS/OptionPSProxy.sol": "OptionPSProxy"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IProxyManager","name":"manager","type":"address"},{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"bool","name":"isCall","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]