编译器
0.8.19+commit.7dd6d404
文件 1 的 48: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 的 48: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 的 48: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 的 48: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 的 48:Constants.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {SD59x18} from "lib/prb-math/src/SD59x18.sol";
import {UD50x28} from "./UD50x28.sol";
import {SD49x28} from "./SD49x28.sol";
UD60x18 constant ZERO = UD60x18.wrap(0);
UD60x18 constant ONE_HALF = UD60x18.wrap(0.5e18);
UD60x18 constant ONE = UD60x18.wrap(1e18);
UD60x18 constant TWO = UD60x18.wrap(2e18);
UD60x18 constant THREE = UD60x18.wrap(3e18);
UD60x18 constant FIVE = UD60x18.wrap(5e18);
SD59x18 constant iZERO = SD59x18.wrap(0);
SD59x18 constant iONE = SD59x18.wrap(1e18);
SD59x18 constant iTWO = SD59x18.wrap(2e18);
SD59x18 constant iFOUR = SD59x18.wrap(4e18);
SD59x18 constant iNINE = SD59x18.wrap(9e18);
UD50x28 constant UD50_ZERO = UD50x28.wrap(0);
UD50x28 constant UD50_ONE = UD50x28.wrap(1e28);
UD50x28 constant UD50_TWO = UD50x28.wrap(2e28);
SD49x28 constant SD49_ZERO = SD49x28.wrap(0);
SD49x28 constant SD49_ONE = SD49x28.wrap(1e28);
SD49x28 constant SD49_TWO = SD49x28.wrap(2e28);
uint256 constant WAD = 1e18;
文件 6 的 48:Conversions.sol
pragma solidity >=0.8.19;
import { uMAX_SD59x18, uMIN_SD59x18, uUNIT } from "./Constants.sol";
import { PRBMath_SD59x18_Convert_Overflow, PRBMath_SD59x18_Convert_Underflow } from "./Errors.sol";
import { SD59x18 } from "./ValueType.sol";
function convert(int256 x) pure returns (SD59x18 result) {
if (x < uMIN_SD59x18 / uUNIT) {
revert PRBMath_SD59x18_Convert_Underflow(x);
}
if (x > uMAX_SD59x18 / uUNIT) {
revert PRBMath_SD59x18_Convert_Overflow(x);
}
unchecked {
result = SD59x18.wrap(x * uUNIT);
}
}
function convert(SD59x18 x) pure returns (int256 result) {
result = SD59x18.unwrap(x) / uUNIT;
}
文件 7 的 48:DoublyLinkedList.sol
pragma solidity ^0.8.0;
library DoublyLinkedList {
struct DoublyLinkedListInternal {
mapping(bytes32 => bytes32) _nextValues;
mapping(bytes32 => bytes32) _prevValues;
}
struct Bytes32List {
DoublyLinkedListInternal _inner;
}
struct AddressList {
DoublyLinkedListInternal _inner;
}
struct Uint256List {
DoublyLinkedListInternal _inner;
}
error DoublyLinkedList__InvalidInput();
error DoublyLinkedList__NonExistentEntry();
function contains(
Bytes32List storage self,
bytes32 value
) internal view returns (bool) {
return _contains(self._inner, value);
}
function contains(
AddressList storage self,
address value
) internal view returns (bool) {
return _contains(self._inner, bytes32(uint256(uint160(value))));
}
function contains(
Uint256List storage self,
uint256 value
) internal view returns (bool) {
return _contains(self._inner, bytes32(value));
}
function prev(
Bytes32List storage self,
bytes32 value
) internal view returns (bytes32) {
return _prev(self._inner, value);
}
function prev(
AddressList storage self,
address value
) internal view returns (address) {
return
address(
uint160(
uint256(
_prev(self._inner, bytes32(uint256(uint160(value))))
)
)
);
}
function prev(
Uint256List storage self,
uint256 value
) internal view returns (uint256) {
return uint256(_prev(self._inner, bytes32(value)));
}
function next(
Bytes32List storage self,
bytes32 value
) internal view returns (bytes32) {
return _next(self._inner, value);
}
function next(
AddressList storage self,
address value
) internal view returns (address) {
return
address(
uint160(
uint256(
_next(self._inner, bytes32(uint256(uint160(value))))
)
)
);
}
function next(
Uint256List storage self,
uint256 value
) internal view returns (uint256) {
return uint256(_next(self._inner, bytes32(value)));
}
function insertBefore(
Bytes32List storage self,
bytes32 nextValue,
bytes32 newValue
) internal returns (bool status) {
status = _insertBefore(self._inner, nextValue, newValue);
}
function insertBefore(
AddressList storage self,
address nextValue,
address newValue
) internal returns (bool status) {
status = _insertBefore(
self._inner,
bytes32(uint256(uint160(nextValue))),
bytes32(uint256(uint160(newValue)))
);
}
function insertBefore(
Uint256List storage self,
uint256 nextValue,
uint256 newValue
) internal returns (bool status) {
status = _insertBefore(
self._inner,
bytes32(nextValue),
bytes32(newValue)
);
}
function insertAfter(
Bytes32List storage self,
bytes32 prevValue,
bytes32 newValue
) internal returns (bool status) {
status = _insertAfter(self._inner, prevValue, newValue);
}
function insertAfter(
AddressList storage self,
address prevValue,
address newValue
) internal returns (bool status) {
status = _insertAfter(
self._inner,
bytes32(uint256(uint160(prevValue))),
bytes32(uint256(uint160(newValue)))
);
}
function insertAfter(
Uint256List storage self,
uint256 prevValue,
uint256 newValue
) internal returns (bool status) {
status = _insertAfter(
self._inner,
bytes32(prevValue),
bytes32(newValue)
);
}
function push(
Bytes32List storage self,
bytes32 value
) internal returns (bool status) {
status = _push(self._inner, value);
}
function push(
AddressList storage self,
address value
) internal returns (bool status) {
status = _push(self._inner, bytes32(uint256(uint160(value))));
}
function push(
Uint256List storage self,
uint256 value
) internal returns (bool status) {
status = _push(self._inner, bytes32(value));
}
function pop(Bytes32List storage self) internal returns (bytes32 value) {
value = _pop(self._inner);
}
function pop(AddressList storage self) internal returns (address value) {
value = address(uint160(uint256(_pop(self._inner))));
}
function pop(Uint256List storage self) internal returns (uint256 value) {
value = uint256(_pop(self._inner));
}
function shift(Bytes32List storage self) internal returns (bytes32 value) {
value = _shift(self._inner);
}
function shift(AddressList storage self) internal returns (address value) {
value = address(uint160(uint256(_shift(self._inner))));
}
function shift(Uint256List storage self) internal returns (uint256 value) {
value = uint256(_shift(self._inner));
}
function unshift(
Bytes32List storage self,
bytes32 value
) internal returns (bool status) {
status = _unshift(self._inner, value);
}
function unshift(
AddressList storage self,
address value
) internal returns (bool status) {
status = _unshift(self._inner, bytes32(uint256(uint160(value))));
}
function unshift(
Uint256List storage self,
uint256 value
) internal returns (bool status) {
status = _unshift(self._inner, bytes32(value));
}
function remove(
Bytes32List storage self,
bytes32 value
) internal returns (bool status) {
status = _remove(self._inner, value);
}
function remove(
AddressList storage self,
address value
) internal returns (bool status) {
status = _remove(self._inner, bytes32(uint256(uint160(value))));
}
function remove(
Uint256List storage self,
uint256 value
) internal returns (bool status) {
status = _remove(self._inner, bytes32(value));
}
function replace(
Bytes32List storage self,
bytes32 oldValue,
bytes32 newValue
) internal returns (bool status) {
status = _replace(self._inner, oldValue, newValue);
}
function replace(
AddressList storage self,
address oldValue,
address newValue
) internal returns (bool status) {
status = _replace(
self._inner,
bytes32(uint256(uint160(oldValue))),
bytes32(uint256(uint160(newValue)))
);
}
function replace(
Uint256List storage self,
uint256 oldValue,
uint256 newValue
) internal returns (bool status) {
status = _replace(self._inner, bytes32(oldValue), bytes32(newValue));
}
function _contains(
DoublyLinkedListInternal storage self,
bytes32 value
) private view returns (bool) {
return
value != 0 &&
(self._nextValues[value] != 0 || self._prevValues[0] == value);
}
function _prev(
DoublyLinkedListInternal storage self,
bytes32 nextValue
) private view returns (bytes32 prevValue) {
prevValue = self._prevValues[nextValue];
if (
nextValue != 0 &&
prevValue == 0 &&
_next(self, prevValue) != nextValue
) revert DoublyLinkedList__NonExistentEntry();
}
function _next(
DoublyLinkedListInternal storage self,
bytes32 prevValue
) private view returns (bytes32 nextValue) {
nextValue = self._nextValues[prevValue];
if (
prevValue != 0 &&
nextValue == 0 &&
_prev(self, nextValue) != prevValue
) revert DoublyLinkedList__NonExistentEntry();
}
function _insertBefore(
DoublyLinkedListInternal storage self,
bytes32 nextValue,
bytes32 newValue
) private returns (bool status) {
status = _insertBetween(
self,
_prev(self, nextValue),
nextValue,
newValue
);
}
function _insertAfter(
DoublyLinkedListInternal storage self,
bytes32 prevValue,
bytes32 newValue
) private returns (bool status) {
status = _insertBetween(
self,
prevValue,
_next(self, prevValue),
newValue
);
}
function _insertBetween(
DoublyLinkedListInternal storage self,
bytes32 prevValue,
bytes32 nextValue,
bytes32 newValue
) private returns (bool status) {
if (newValue == 0) revert DoublyLinkedList__InvalidInput();
if (!_contains(self, newValue)) {
_link(self, prevValue, newValue);
_link(self, newValue, nextValue);
status = true;
}
}
function _push(
DoublyLinkedListInternal storage self,
bytes32 value
) private returns (bool status) {
status = _insertBetween(self, _prev(self, 0), 0, value);
}
function _pop(
DoublyLinkedListInternal storage self
) private returns (bytes32 value) {
value = _prev(self, 0);
_remove(self, value);
}
function _shift(
DoublyLinkedListInternal storage self
) private returns (bytes32 value) {
value = _next(self, 0);
_remove(self, value);
}
function _unshift(
DoublyLinkedListInternal storage self,
bytes32 value
) private returns (bool status) {
status = _insertBetween(self, 0, _next(self, 0), value);
}
function _remove(
DoublyLinkedListInternal storage self,
bytes32 value
) private returns (bool status) {
if (_contains(self, value)) {
_link(self, _prev(self, value), _next(self, value));
delete self._prevValues[value];
delete self._nextValues[value];
status = true;
}
}
function _replace(
DoublyLinkedListInternal storage self,
bytes32 oldValue,
bytes32 newValue
) private returns (bool status) {
if (!_contains(self, oldValue))
revert DoublyLinkedList__NonExistentEntry();
status = _insertBetween(
self,
_prev(self, oldValue),
_next(self, oldValue),
newValue
);
if (status) {
delete self._prevValues[oldValue];
delete self._nextValues[oldValue];
}
}
function _link(
DoublyLinkedListInternal storage self,
bytes32 prevValue,
bytes32 nextValue
) private {
self._nextValues[prevValue] = nextValue;
self._prevValues[nextValue] = prevValue;
}
}
文件 8 的 48:ERC20MetadataStorage.sol
pragma solidity ^0.8.8;
library ERC20MetadataStorage {
struct Layout {
string name;
string symbol;
uint8 decimals;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.ERC20Metadata');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
文件 9 的 48:ERC4626BaseStorage.sol
pragma solidity ^0.8.8;
library ERC4626BaseStorage {
struct Layout {
address asset;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.ERC4626Base');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
文件 10 的 48: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;
}
}
}
文件 11 的 48:EnumerableSetUD60x18.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {EnumerableSet} from "@solidstate/contracts/data/EnumerableSet.sol";
library EnumerableSetUD60x18 {
using EnumerableSet for EnumerableSet.Bytes32Set;
function at(EnumerableSet.Bytes32Set storage self, uint256 i) internal view returns (UD60x18) {
return UD60x18.wrap(uint256(self.at(i)));
}
function contains(EnumerableSet.Bytes32Set storage self, UD60x18 value) internal view returns (bool) {
return self.contains(bytes32(value.unwrap()));
}
function indexOf(EnumerableSet.Bytes32Set storage self, UD60x18 value) internal view returns (uint256) {
return self.indexOf(bytes32(value.unwrap()));
}
function length(EnumerableSet.Bytes32Set storage self) internal view returns (uint256) {
return self.length();
}
function add(EnumerableSet.Bytes32Set storage self, UD60x18 value) internal returns (bool) {
return self.add(bytes32(value.unwrap()));
}
function remove(EnumerableSet.Bytes32Set storage self, UD60x18 value) internal returns (bool) {
return self.remove(bytes32(value.unwrap()));
}
function toArray(EnumerableSet.Bytes32Set storage self) internal view returns (UD60x18[] memory) {
bytes32[] memory src = self.toArray();
UD60x18[] memory tgt = new UD60x18[](src.length);
for (uint256 i = 0; i < src.length; i++) {
tgt[i] = UD60x18.wrap(uint256(src[i]));
}
return tgt;
}
}
文件 12 的 48:Errors.sol
pragma solidity >=0.8.19;
import { SD59x18 } from "./ValueType.sol";
error PRBMath_SD59x18_Abs_MinSD59x18();
error PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);
error PRBMath_SD59x18_Convert_Overflow(int256 x);
error PRBMath_SD59x18_Convert_Underflow(int256 x);
error PRBMath_SD59x18_Div_InputTooSmall();
error PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);
error PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);
error PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);
error PRBMath_SD59x18_Floor_Underflow(SD59x18 x);
error PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);
error PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);
error PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);
error PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);
error PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);
error PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);
error PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);
error PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);
error PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);
error PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);
error PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);
error PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);
error PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);
error PRBMath_SD59x18_Mul_InputTooSmall();
error PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);
error PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);
error PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);
error PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);
文件 13 的 48:Helpers.sol
pragma solidity >=0.8.19;
import { wrap } from "./Casting.sol";
import { SD59x18 } from "./ValueType.sol";
function add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
return wrap(x.unwrap() + y.unwrap());
}
function and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {
return wrap(x.unwrap() & bits);
}
function and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
return wrap(x.unwrap() & y.unwrap());
}
function eq(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() == y.unwrap();
}
function gt(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() > y.unwrap();
}
function gte(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() >= y.unwrap();
}
function isZero(SD59x18 x) pure returns (bool result) {
result = x.unwrap() == 0;
}
function lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {
result = wrap(x.unwrap() << bits);
}
function lt(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() < y.unwrap();
}
function lte(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() <= y.unwrap();
}
function mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() % y.unwrap());
}
function neq(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() != y.unwrap();
}
function not(SD59x18 x) pure returns (SD59x18 result) {
result = wrap(~x.unwrap());
}
function or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() | y.unwrap());
}
function rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {
result = wrap(x.unwrap() >> bits);
}
function sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() - y.unwrap());
}
function unary(SD59x18 x) pure returns (SD59x18 result) {
result = wrap(-x.unwrap());
}
function uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
unchecked {
result = wrap(x.unwrap() + y.unwrap());
}
}
function uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
unchecked {
result = wrap(x.unwrap() - y.unwrap());
}
}
function uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {
unchecked {
result = wrap(-x.unwrap());
}
}
function xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() ^ y.unwrap());
}
文件 14 的 48: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);
}
文件 15 的 48:IERC20Base.sol
pragma solidity ^0.8.8;
import { IERC20 } from '../../../interfaces/IERC20.sol';
import { IERC20BaseInternal } from './IERC20BaseInternal.sol';
interface IERC20Base is IERC20BaseInternal, IERC20 {
}
文件 16 的 48:IERC20BaseInternal.sol
pragma solidity ^0.8.8;
import { IERC20Internal } from '../../../interfaces/IERC20Internal.sol';
interface IERC20BaseInternal is IERC20Internal {
error ERC20Base__ApproveFromZeroAddress();
error ERC20Base__ApproveToZeroAddress();
error ERC20Base__BurnExceedsBalance();
error ERC20Base__BurnFromZeroAddress();
error ERC20Base__InsufficientAllowance();
error ERC20Base__MintToZeroAddress();
error ERC20Base__TransferExceedsBalance();
error ERC20Base__TransferFromZeroAddress();
error ERC20Base__TransferToZeroAddress();
}
文件 17 的 48:IERC20Extended.sol
pragma solidity ^0.8.8;
import { IERC20ExtendedInternal } from './IERC20ExtendedInternal.sol';
interface IERC20Extended is IERC20ExtendedInternal {
function increaseAllowance(
address spender,
uint256 amount
) external returns (bool);
function decreaseAllowance(
address spender,
uint256 amount
) external returns (bool);
}
文件 18 的 48:IERC20ExtendedInternal.sol
pragma solidity ^0.8.8;
import { IERC20BaseInternal } from '../base/IERC20BaseInternal.sol';
interface IERC20ExtendedInternal is IERC20BaseInternal {
error ERC20Extended__ExcessiveAllowance();
error ERC20Extended__InsufficientAllowance();
}
文件 19 的 48: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
);
}
文件 20 的 48: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);
}
文件 21 的 48:IERC20MetadataInternal.sol
pragma solidity ^0.8.8;
interface IERC20MetadataInternal {
}
文件 22 的 48:IERC20Permit.sol
pragma solidity ^0.8.8;
import { IERC20Metadata } from '../metadata/IERC20Metadata.sol';
import { IERC2612 } from './IERC2612.sol';
import { IERC20PermitInternal } from './IERC20PermitInternal.sol';
interface IERC20Permit is IERC20PermitInternal, IERC2612 {
}
文件 23 的 48:IERC20PermitInternal.sol
pragma solidity ^0.8.8;
import { IERC2612Internal } from './IERC2612Internal.sol';
interface IERC20PermitInternal is IERC2612Internal {
error ERC20Permit__ExpiredDeadline();
error ERC20Permit__InvalidSignature();
}
文件 24 的 48:IERC2612.sol
pragma solidity ^0.8.8;
import { IERC2612Internal } from './IERC2612Internal.sol';
interface IERC2612 is IERC2612Internal {
function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
文件 25 的 48:IERC2612Internal.sol
pragma solidity ^0.8.8;
interface IERC2612Internal {}
文件 26 的 48:IERC4626.sol
pragma solidity ^0.8.8;
import { IERC20Metadata } from '../token/ERC20/metadata/IERC20Metadata.sol';
import { IERC20 } from './IERC20.sol';
import { IERC4626Internal } from './IERC4626Internal.sol';
interface IERC4626 is IERC4626Internal, IERC20, IERC20Metadata {
function asset() external view returns (address);
function totalAssets() external view returns (uint256);
function convertToShares(
uint256 assetAmount
) external view returns (uint256 shareAmount);
function convertToAssets(
uint256 shareAmount
) external view returns (uint256 assetAmount);
function maxDeposit(
address receiver
) external view returns (uint256 maxAssets);
function maxMint(
address receiver
) external view returns (uint256 maxShares);
function maxWithdraw(
address owner
) external view returns (uint256 maxAssets);
function maxRedeem(address owner) external view returns (uint256 maxShares);
function previewDeposit(
uint256 assetAmount
) external view returns (uint256 shareAmount);
function previewMint(
uint256 shareAmount
) external view returns (uint256 assetAmount);
function previewWithdraw(
uint256 assetAmount
) external view returns (uint256 shareAmount);
function previewRedeem(
uint256 shareAmount
) external view returns (uint256 assetAmount);
function deposit(
uint256 assetAmount,
address receiver
) external returns (uint256 shareAmount);
function mint(
uint256 shareAmount,
address receiver
) external returns (uint256 assetAmount);
function withdraw(
uint256 assetAmount,
address receiver,
address owner
) external returns (uint256 shareAmount);
function redeem(
uint256 shareAmount,
address receiver,
address owner
) external returns (uint256 assetAmount);
}
文件 27 的 48:IERC4626Base.sol
pragma solidity ^0.8.8;
import { IERC4626 } from '../../../interfaces/IERC4626.sol';
import { IERC4626BaseInternal } from './IERC4626BaseInternal.sol';
interface IERC4626Base is IERC4626BaseInternal, IERC4626 {
}
文件 28 的 48:IERC4626BaseInternal.sol
pragma solidity ^0.8.8;
import { IERC4626Internal } from '../../../interfaces/IERC4626Internal.sol';
interface IERC4626BaseInternal is IERC4626Internal {
error ERC4626Base__MaximumAmountExceeded();
error ERC4626Base__AllowanceExceeded();
}
文件 29 的 48:IERC4626Internal.sol
pragma solidity ^0.8.8;
interface IERC4626Internal {
event Deposit(
address indexed caller,
address indexed owner,
uint256 assets,
uint256 shares
);
event Withdraw(
address indexed caller,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
}
文件 30 的 48:IOracleAdapter.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
interface IOracleAdapter {
enum AdapterType {
None,
Chainlink
}
error OracleAdapter__ArrayCannotExpand(uint256 arrayLength, uint256 size);
error OracleAdapter__InvalidTarget(uint256 target, uint256 blockTimestamp);
error OracleAdapter__InvalidPrice(int256 price);
error OracleAdapter__PairCannotBeSupported(address tokenA, address tokenB);
error OracleAdapter__PairNotSupported(address tokenA, address tokenB);
error OracleAdapter__TokensAreSame(address tokenA, address tokenB);
error OracleAdapter__ZeroAddress();
function isPairSupported(address tokenA, address tokenB) external view returns (bool isCached, bool hasPath);
function upsertPair(address tokenA, address tokenB) external;
function getPrice(address tokenIn, address tokenOut) external view returns (UD60x18);
function getPriceAt(address tokenIn, address tokenOut, uint256 target) external view returns (UD60x18);
function describePricingPath(
address token
) external view returns (AdapterType adapterType, address[][] memory path, uint8[] memory decimals);
}
文件 31 的 48:IPoolFactory.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {IPoolFactoryEvents} from "./IPoolFactoryEvents.sol";
interface IPoolFactory is IPoolFactoryEvents {
error PoolFactory__IdenticalAddresses();
error PoolFactory__InitializationFeeIsZero();
error PoolFactory__InitializationFeeRequired(uint256 msgValue, uint256 fee);
error PoolFactory__InvalidInput();
error PoolFactory__NotAuthorized();
error PoolFactory__OptionExpired(uint256 maturity);
error PoolFactory__OptionMaturityExceedsMax(uint256 maturity);
error PoolFactory__OptionMaturityNot8UTC(uint256 maturity);
error PoolFactory__OptionMaturityNotFriday(uint256 maturity);
error PoolFactory__OptionMaturityNotLastFriday(uint256 maturity);
error PoolFactory__OptionStrikeEqualsZero();
error PoolFactory__OptionStrikeInvalid(UD60x18 strike, UD60x18 strikeInterval);
error PoolFactory__PoolAlreadyDeployed(address poolAddress);
error PoolFactory__PoolNotExpired();
error PoolFactory__TransferNativeTokenFailed();
error PoolFactory__ZeroAddress();
struct PoolKey {
address base;
address quote;
address oracleAdapter;
UD60x18 strike;
uint256 maturity;
bool isCallPool;
}
function isPool(address contractAddress) external view returns (bool);
function getPoolAddress(PoolKey calldata k) external view returns (address pool, bool isDeployed);
function setDiscountPerPool(UD60x18 discountPerPool) external;
function setFeeReceiver(address feeReceiver) external;
function deployPool(PoolKey calldata k) external payable returns (address poolAddress);
function removeDiscount(PoolKey calldata k) external;
function initializationFee(PoolKey calldata k) external view returns (UD60x18);
}
文件 32 的 48:IPoolFactoryEvents.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {IOracleAdapter} from "../adapter/IOracleAdapter.sol";
interface IPoolFactoryEvents {
event SetDiscountPerPool(UD60x18 indexed discountPerPool);
event SetFeeReceiver(address indexed feeReceiver);
event PoolDeployed(
address indexed base,
address indexed quote,
address oracleAdapter,
UD60x18 strike,
uint256 maturity,
bool isCallPool,
address poolAddress
);
event PricingPath(
address pool,
address[][] basePath,
uint8[] basePathDecimals,
IOracleAdapter.AdapterType baseAdapterType,
address[][] quotePath,
uint8[] quotePathDecimals,
IOracleAdapter.AdapterType quoteAdapterType
);
}
文件 33 的 48:IProxy.sol
pragma solidity ^0.8.8;
interface IProxy {
error Proxy__ImplementationIsNotContract();
fallback() external payable;
}
文件 34 的 48:ISolidStateERC20.sol
pragma solidity ^0.8.8;
import { IERC20Base } from './base/IERC20Base.sol';
import { IERC20Extended } from './extended/IERC20Extended.sol';
import { IERC20Metadata } from './metadata/IERC20Metadata.sol';
import { IERC20Permit } from './permit/IERC20Permit.sol';
interface ISolidStateERC20 is
IERC20Base,
IERC20Extended,
IERC20Metadata,
IERC20Permit
{}
文件 35 的 48:ISolidStateERC4626.sol
pragma solidity ^0.8.8;
import { ISolidStateERC20 } from '../ERC20/ISolidStateERC20.sol';
import { IERC4626Base } from './base/IERC4626Base.sol';
interface ISolidStateERC4626 is IERC4626Base, ISolidStateERC20 {}
文件 36 的 48:IVault.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {ISolidStateERC4626} from "@solidstate/contracts/token/ERC4626/ISolidStateERC4626.sol";
import {IPoolFactory} from "../factory/IPoolFactory.sol";
interface IVault is ISolidStateERC4626 {
error Vault__AboveMaxSlippage(UD60x18 totalPremium, UD60x18 premiumLimit);
error Vault__AddressZero();
error Vault__InsufficientFunds();
error Vault__InvalidSettingsUpdate();
error Vault__InvariantViolated();
error Vault__MaximumAmountExceeded(UD60x18 maximum, UD60x18 amount);
error Vault__NotAuthorized();
error Vault__OptionExpired(uint256 timestamp, uint256 maturity);
error Vault__OptionPoolNotListed();
error Vault__OptionTypeMismatchWithVault();
error Vault__OutOfDeltaBounds();
error Vault__OutOfDTEBounds();
error Vault__SettingsNotFromRegistry();
error Vault__SettingsUpdateIsEmpty();
error Vault__StrikeZero();
error Vault__TradeMustBeBuy();
error Vault__TransferExceedsBalance(UD60x18 balance, UD60x18 amount);
error Vault__ZeroAsset();
error Vault__ZeroShares();
error Vault__ZeroSize();
event UpdateQuotes();
event PricePerShare(UD60x18 pricePerShare);
event Trade(
address indexed user,
address indexed pool,
UD60x18 contractSize,
bool isBuy,
UD60x18 premium,
UD60x18 takerFee,
UD60x18 makerRebate,
UD60x18 vaultFee
);
event Settle(address indexed pool, UD60x18 contractSize, UD60x18 fee);
event ManagementFeePaid(address indexed recipient, uint256 managementFee);
event PerformanceFeePaid(address indexed recipient, uint256 performanceFee);
event ClaimProtocolFees(address indexed feeReceiver, uint256 feesClaimed);
event UpdateSettings(bytes settings);
function updateSettings(bytes memory settings) external;
function getSettings() external view returns (bytes memory);
function getQuote(
IPoolFactory.PoolKey calldata poolKey,
UD60x18 size,
bool isBuy,
address taker
) external view returns (uint256 premium);
function trade(
IPoolFactory.PoolKey calldata poolKey,
UD60x18 size,
bool isBuy,
uint256 premiumLimit,
address referrer
) external;
function getUtilisation() external view returns (UD60x18);
}
文件 37 的 48:IVaultRegistry.sol
pragma solidity ^0.8.19;
interface IVaultRegistry {
enum TradeSide {
Buy,
Sell,
Both
}
enum OptionType {
Call,
Put,
Both
}
struct Vault {
address vault;
address asset;
bytes32 vaultType;
TradeSide side;
OptionType optionType;
}
struct TokenPair {
address base;
address quote;
address oracleAdapter;
}
event VaultImplementationSet(bytes32 indexed vaultType, address implementation);
event VaultAdded(
address indexed vault,
address indexed asset,
bytes32 vaultType,
TradeSide side,
OptionType optionType
);
event VaultRemoved(address indexed vault);
event VaultUpdated(
address indexed vault,
address indexed asset,
bytes32 vaultType,
TradeSide side,
OptionType optionType
);
event SupportedTokenPairAdded(
address indexed vault,
address indexed base,
address indexed quote,
address oracleAdapter
);
event SupportedTokenPairRemoved(
address indexed vault,
address indexed base,
address indexed quote,
address oracleAdapter
);
function getNumberOfVaults() external view returns (uint256);
function addVault(address vault, address asset, bytes32 vaultType, TradeSide side, OptionType optionType) external;
function removeVault(address vault) external;
function isVault(address vault) external view returns (bool);
function updateVault(
address vault,
address asset,
bytes32 vaultType,
TradeSide side,
OptionType optionType
) external;
function addSupportedTokenPairs(address vault, TokenPair[] memory tokenPairs) external;
function removeSupportedTokenPairs(address vault, TokenPair[] memory tokenPairsToRemove) external;
function getVault(address vault) external view returns (Vault memory);
function getSupportedTokenPairs(address vault) external view returns (TokenPair[] memory);
function getVaults() external view returns (Vault[] memory);
function getVaultsByFilter(
address[] memory assets,
TradeSide side,
OptionType optionType
) external view returns (Vault[] memory);
function getVaultsByAsset(address asset) external view returns (Vault[] memory);
function getVaultsByTokenPair(TokenPair memory tokenPair) external view returns (Vault[] memory);
function getVaultsByTradeSide(TradeSide side) external view returns (Vault[] memory);
function getVaultsByOptionType(OptionType optionType) external view returns (Vault[] memory);
function getVaultsByType(bytes32 vaultType) external view returns (Vault[] memory);
function getImplementation(bytes32 vaultType) external view returns (address);
function setImplementation(bytes32 vaultType, address implementation) external;
}
文件 38 的 48: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));
}
}
文件 39 的 48: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;
}
}
文件 40 的 48: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);
}
文件 41 的 48: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;
文件 42 的 48: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";
文件 43 的 48: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;
文件 44 的 48: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";
文件 45 的 48: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);
}
}
文件 46 的 48:UnderwriterVaultProxy.sol
pragma solidity =0.8.19;
import {Proxy} from "@solidstate/contracts/proxy/Proxy.sol";
import {ERC20MetadataStorage} from "@solidstate/contracts/token/ERC20/metadata/ERC20MetadataStorage.sol";
import {IERC20Metadata} from "@solidstate/contracts/token/ERC20/metadata/IERC20Metadata.sol";
import {ERC4626BaseStorage} from "@solidstate/contracts/token/ERC4626/base/ERC4626BaseStorage.sol";
import {UnderwriterVaultStorage} from "./UnderwriterVaultStorage.sol";
import {IVaultRegistry} from "../../IVaultRegistry.sol";
contract UnderwriterVaultProxy is Proxy {
using UnderwriterVaultStorage for UnderwriterVaultStorage.Layout;
bytes32 public constant VAULT_TYPE = keccak256("UnderwriterVault");
address internal immutable VAULT_REGISTRY;
constructor(
address vaultRegistry,
address base,
address quote,
address oracleAdapter,
string memory name,
string memory symbol,
bool isCall,
bytes memory settings
) {
VAULT_REGISTRY = vaultRegistry;
ERC20MetadataStorage.Layout storage metadata = ERC20MetadataStorage.layout();
metadata.name = name;
metadata.symbol = symbol;
metadata.decimals = 18;
ERC4626BaseStorage.layout().asset = isCall ? base : quote;
UnderwriterVaultStorage.Layout storage l = UnderwriterVaultStorage.layout();
l.updateSettings(settings);
l.isCall = isCall;
l.base = base;
l.quote = quote;
uint8 baseDecimals = IERC20Metadata(base).decimals();
uint8 quoteDecimals = IERC20Metadata(quote).decimals();
l.baseDecimals = baseDecimals;
l.quoteDecimals = quoteDecimals;
l.lastTradeTimestamp = block.timestamp;
l.oracleAdapter = oracleAdapter;
}
receive() external payable {}
function _getImplementation() internal view override returns (address) {
return IVaultRegistry(VAULT_REGISTRY).getImplementation(VAULT_TYPE);
}
function getImplementation() external view returns (address) {
return _getImplementation();
}
}
文件 47 的 48:UnderwriterVaultStorage.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {DoublyLinkedList} from "@solidstate/contracts/data/DoublyLinkedList.sol";
import {IVault} from "../../IVault.sol";
import {EnumerableSetUD60x18, EnumerableSet} from "../../../libraries/EnumerableSetUD60x18.sol";
import {OptionMath} from "../../../libraries/OptionMath.sol";
import {ONE} from "contracts/libraries/Constants.sol";
library UnderwriterVaultStorage {
using UnderwriterVaultStorage for UnderwriterVaultStorage.Layout;
using DoublyLinkedList for DoublyLinkedList.Uint256List;
using EnumerableSetUD60x18 for EnumerableSet.Bytes32Set;
bytes32 internal constant STORAGE_SLOT = keccak256("premia.contracts.storage.UnderwriterVaultStorage");
struct Layout {
address base;
address quote;
uint8 baseDecimals;
uint8 quoteDecimals;
address oracleAdapter;
bool isCall;
UD60x18 totalAssets;
UD60x18 totalLockedAssets;
UD60x18 minDTE;
UD60x18 maxDTE;
UD60x18 minDelta;
UD60x18 maxDelta;
UD60x18 minCLevel;
UD60x18 maxCLevel;
UD60x18 alphaCLevel;
UD60x18 hourlyDecayDiscount;
uint256 lastTradeTimestamp;
uint256 minMaturity;
uint256 maxMaturity;
DoublyLinkedList.Uint256List maturities;
mapping(uint256 => EnumerableSet.Bytes32Set) maturityToStrikes;
mapping(uint256 => mapping(UD60x18 => UD60x18)) positionSizes;
UD60x18 totalLockedSpread;
UD60x18 spreadUnlockingRate;
uint256 lastSpreadUnlockUpdate;
mapping(uint256 => UD60x18) spreadUnlockingTicks;
UD60x18 managementFeeRate;
UD60x18 performanceFeeRate;
UD60x18 protocolFees;
uint256 lastManagementFeeTimestamp;
uint256 pendingAssetsDeposit;
}
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
function updateSettings(Layout storage l, bytes memory settings) internal {
if (settings.length == 0) revert IVault.Vault__SettingsUpdateIsEmpty();
UD60x18[] memory arr = abi.decode(settings, (UD60x18[]));
if (arr[2] < ONE) revert IVault.Vault__InvalidSettingsUpdate();
l.alphaCLevel = arr[0];
l.hourlyDecayDiscount = arr[1];
l.minCLevel = arr[2];
l.maxCLevel = arr[3];
l.minDTE = arr[4];
l.maxDTE = arr[5];
l.minDelta = arr[6];
l.maxDelta = arr[7];
l.performanceFeeRate = arr[8];
l.managementFeeRate = arr[9];
}
function assetDecimals(Layout storage l) internal view returns (uint8) {
return l.isCall ? l.baseDecimals : l.quoteDecimals;
}
function collateral(Layout storage l, UD60x18 size, UD60x18 strike) internal view returns (UD60x18) {
return l.isCall ? size : size * strike;
}
function convertAssetToUD60x18(Layout storage l, uint256 value) internal view returns (UD60x18) {
return UD60x18.wrap(OptionMath.scaleDecimals(value, l.assetDecimals(), 18));
}
function convertAssetFromUD60x18(Layout storage l, UD60x18 value) internal view returns (uint256) {
return OptionMath.scaleDecimals(value.unwrap(), 18, l.assetDecimals());
}
function getMaturityAfterTimestamp(Layout storage l, uint256 timestamp) internal view returns (uint256) {
uint256 current = l.minMaturity;
while (current <= timestamp && current != 0) {
current = l.maturities.next(current);
}
return current;
}
function getNumberOfUnexpiredListings(Layout storage l, uint256 timestamp) internal view returns (uint256) {
uint256 n = 0;
if (l.maxMaturity <= timestamp) return 0;
uint256 current = l.getMaturityAfterTimestamp(timestamp);
while (current <= l.maxMaturity && current != 0) {
n += l.maturityToStrikes[current].length();
current = l.maturities.next(current);
}
return n;
}
function contains(Layout storage l, UD60x18 strike, uint256 maturity) internal view returns (bool) {
if (!l.maturities.contains(maturity)) return false;
return l.maturityToStrikes[maturity].contains(strike);
}
function addListing(Layout storage l, UD60x18 strike, uint256 maturity) internal {
if (!l.maturities.contains(maturity)) {
if (maturity < l.minMaturity) {
l.maturities.insertBefore(l.minMaturity, maturity);
l.minMaturity = maturity;
} else if ((l.minMaturity < maturity) && (maturity) < l.maxMaturity) {
uint256 next = l.getMaturityAfterTimestamp(maturity);
l.maturities.insertBefore(next, maturity);
} else {
l.maturities.insertAfter(l.maxMaturity, maturity);
if (l.minMaturity == 0) l.minMaturity = maturity;
l.maxMaturity = maturity;
}
}
if (!l.maturityToStrikes[maturity].contains(strike)) l.maturityToStrikes[maturity].add(strike);
}
function removeListing(Layout storage l, UD60x18 strike, uint256 maturity) internal {
if (l.contains(strike, maturity)) {
l.maturityToStrikes[maturity].remove(strike);
if (l.maturityToStrikes[maturity].length() == 0) {
if (maturity == l.minMaturity) l.minMaturity = l.maturities.next(maturity);
if (maturity == l.maxMaturity) l.maxMaturity = l.maturities.prev(maturity);
l.maturities.remove(maturity);
}
}
}
}
文件 48 的 48: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/vault/strategies/underwriter/UnderwriterVaultProxy.sol": "UnderwriterVaultProxy"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"vaultRegistry","type":"address"},{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"address","name":"oracleAdapter","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"bool","name":"isCall","type":"bool"},{"internalType":"bytes","name":"settings","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"Vault__InvalidSettingsUpdate","type":"error"},{"inputs":[],"name":"Vault__SettingsUpdateIsEmpty","type":"error"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"VAULT_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]