编译器
0.8.19+commit.7dd6d404
文件 1 的 46: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 的 46: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 的 46:Casting.sol
pragma solidity >=0.8.19;
import "../Common.sol" as Common;
import "./Errors.sol" as Errors;
import { uMAX_SD1x18 } from "../sd1x18/Constants.sol";
import { SD1x18 } from "../sd1x18/ValueType.sol";
import { SD59x18 } from "../sd59x18/ValueType.sol";
import { UD2x18 } from "../ud2x18/ValueType.sol";
import { UD60x18 } from "../ud60x18/ValueType.sol";
import { UD2x18 } from "./ValueType.sol";
function intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {
uint64 xUint = UD2x18.unwrap(x);
if (xUint > uint64(uMAX_SD1x18)) {
revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);
}
result = SD1x18.wrap(int64(xUint));
}
function intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {
result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));
}
function intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {
result = UD60x18.wrap(UD2x18.unwrap(x));
}
function intoUint128(UD2x18 x) pure returns (uint128 result) {
result = uint128(UD2x18.unwrap(x));
}
function intoUint256(UD2x18 x) pure returns (uint256 result) {
result = uint256(UD2x18.unwrap(x));
}
function intoUint40(UD2x18 x) pure returns (uint40 result) {
uint64 xUint = UD2x18.unwrap(x);
if (xUint > uint64(Common.MAX_UINT40)) {
revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);
}
result = uint40(xUint);
}
function ud2x18(uint64 x) pure returns (UD2x18 result) {
result = UD2x18.wrap(x);
}
function unwrap(UD2x18 x) pure returns (uint64 result) {
result = UD2x18.unwrap(x);
}
function wrap(uint64 x) pure returns (UD2x18 result) {
result = UD2x18.wrap(x);
}
文件 4 的 46: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 的 46:Constants.sol
pragma solidity >=0.8.19;
import { SD59x18 } from "./ValueType.sol";
SD59x18 constant E = SD59x18.wrap(2_718281828459045235);
int256 constant uEXP_MAX_INPUT = 133_084258667509499440;
SD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);
int256 constant uEXP2_MAX_INPUT = 192e18 - 1;
SD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);
int256 constant uHALF_UNIT = 0.5e18;
SD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);
int256 constant uLOG2_10 = 3_321928094887362347;
SD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);
int256 constant uLOG2_E = 1_442695040888963407;
SD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);
int256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;
SD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);
int256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;
SD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);
int256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;
SD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);
int256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;
SD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);
SD59x18 constant PI = SD59x18.wrap(3_141592653589793238);
int256 constant uUNIT = 1e18;
SD59x18 constant UNIT = SD59x18.wrap(1e18);
int256 constant uUNIT_SQUARED = 1e36;
SD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);
SD59x18 constant ZERO = SD59x18.wrap(0);
文件 6 的 46: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 的 46: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 的 46:DoublyLinkedListUD60x18.sol
pragma solidity ^0.8.19;
import {UD60x18, ud} from "lib/prb-math/src/UD60x18.sol";
import {DoublyLinkedList} from "@solidstate/contracts/data/DoublyLinkedList.sol";
library DoublyLinkedListUD60x18 {
using DoublyLinkedList for DoublyLinkedList.Bytes32List;
function contains(DoublyLinkedList.Bytes32List storage self, UD60x18 value) internal view returns (bool) {
return self.contains(bytes32(value.unwrap()));
}
function prev(DoublyLinkedList.Bytes32List storage self, UD60x18 value) internal view returns (UD60x18) {
return ud(uint256(self.prev(bytes32(value.unwrap()))));
}
function next(DoublyLinkedList.Bytes32List storage self, UD60x18 value) internal view returns (UD60x18) {
return ud(uint256(self.next(bytes32(value.unwrap()))));
}
function insertBefore(
DoublyLinkedList.Bytes32List storage self,
UD60x18 nextValue,
UD60x18 newValue
) internal returns (bool status) {
status = self.insertBefore(bytes32(nextValue.unwrap()), bytes32(newValue.unwrap()));
}
function insertAfter(
DoublyLinkedList.Bytes32List storage self,
UD60x18 prevValue,
UD60x18 newValue
) internal returns (bool status) {
status = self.insertAfter(bytes32(prevValue.unwrap()), bytes32(newValue.unwrap()));
}
function push(DoublyLinkedList.Bytes32List storage self, UD60x18 value) internal returns (bool status) {
status = self.push(bytes32(value.unwrap()));
}
function pop(DoublyLinkedList.Bytes32List storage self) internal returns (UD60x18 value) {
value = ud(uint256(self.pop()));
}
function shift(DoublyLinkedList.Bytes32List storage self) internal returns (UD60x18 value) {
value = ud(uint256(self.shift()));
}
function unshift(DoublyLinkedList.Bytes32List storage self, UD60x18 value) internal returns (bool status) {
status = self.unshift(bytes32(value.unwrap()));
}
function remove(DoublyLinkedList.Bytes32List storage self, UD60x18 value) internal returns (bool status) {
status = self.remove(bytes32(value.unwrap()));
}
function replace(
DoublyLinkedList.Bytes32List storage self,
UD60x18 oldValue,
UD60x18 newValue
) internal returns (bool status) {
status = self.replace(bytes32(oldValue.unwrap()), bytes32(newValue.unwrap()));
}
}
文件 9 的 46:ERC165BaseInternal.sol
pragma solidity ^0.8.8;
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';
abstract contract ERC165BaseInternal is IERC165BaseInternal {
function _supportsInterface(
bytes4 interfaceId
) internal view virtual returns (bool) {
return ERC165BaseStorage.layout().supportedInterfaces[interfaceId];
}
function _setSupportsInterface(
bytes4 interfaceId,
bool status
) internal virtual {
if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
}
}
文件 10 的 46:ERC165BaseStorage.sol
pragma solidity ^0.8.8;
library ERC165BaseStorage {
struct Layout {
mapping(bytes4 => bool) supportedInterfaces;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.ERC165Base');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
文件 11 的 46: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;
}
}
}
文件 12 的 46:Errors.sol
pragma solidity >=0.8.19;
import { UD60x18 } from "./ValueType.sol";
error PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);
error PRBMath_UD60x18_Convert_Overflow(uint256 x);
error PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);
error PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);
error PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);
error PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);
error PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);
error PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);
error PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);
error PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);
error PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);
error PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);
文件 13 的 46: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 的 46:IDiamondReadable.sol
pragma solidity ^0.8.8;
interface IDiamondReadable {
struct Facet {
address target;
bytes4[] selectors;
}
function facets() external view returns (Facet[] memory diamondFacets);
function facetFunctionSelectors(
address facet
) external view returns (bytes4[] memory selectors);
function facetAddresses()
external
view
returns (address[] memory addresses);
function facetAddress(
bytes4 selector
) external view returns (address facet);
}
文件 15 的 46:IERC1155.sol
pragma solidity ^0.8.8;
import { IERC165 } from './IERC165.sol';
import { IERC1155Internal } from './IERC1155Internal.sol';
interface IERC1155 is IERC1155Internal, IERC165 {
function balanceOf(
address account,
uint256 id
) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
function isApprovedForAll(
address account,
address operator
) external view returns (bool);
function setApprovalForAll(address operator, bool status) external;
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 16 的 46:IERC1155Internal.sol
pragma solidity ^0.8.8;
interface IERC1155Internal {
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 value
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(
address indexed account,
address indexed operator,
bool approved
);
}
文件 17 的 46:IERC165.sol
pragma solidity ^0.8.8;
import { IERC165Internal } from './IERC165Internal.sol';
interface IERC165 is IERC165Internal {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 18 的 46:IERC165BaseInternal.sol
pragma solidity ^0.8.0;
import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';
interface IERC165BaseInternal is IERC165Internal {
error ERC165Base__InvalidInterfaceId();
}
文件 19 的 46:IERC165Internal.sol
pragma solidity ^0.8.8;
interface IERC165Internal {
}
文件 20 的 46:IERC20.sol
pragma solidity ^0.8.8;
import { IERC20Internal } from './IERC20Internal.sol';
interface IERC20 is IERC20Internal {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(
address holder,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function transferFrom(
address holder,
address recipient,
uint256 amount
) external returns (bool);
}
文件 21 的 46:IERC20Internal.sol
pragma solidity ^0.8.8;
interface IERC20Internal {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
文件 22 的 46:IERC20Metadata.sol
pragma solidity ^0.8.8;
import { IERC20MetadataInternal } from './IERC20MetadataInternal.sol';
interface IERC20Metadata is IERC20MetadataInternal {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 23 的 46:IERC20MetadataInternal.sol
pragma solidity ^0.8.8;
interface IERC20MetadataInternal {
}
文件 24 的 46:IERC20Router.sol
pragma solidity ^0.8.19;
interface IERC20Router {
error ERC20Router__NotAuthorized();
function safeTransferFrom(address token, address from, address to, uint256 amount) external;
}
文件 25 的 46:IMulticall.sol
pragma solidity ^0.8.8;
interface IMulticall {
function multicall(
bytes[] calldata data
) external returns (bytes[] memory results);
}
文件 26 的 46:IPoolInternal.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 {IPosition} from "../libraries/IPosition.sol";
import {IPricing} from "../libraries/IPricing.sol";
import {UD50x28} from "../libraries/UD50x28.sol";
import {SD49x28} from "../libraries/SD49x28.sol";
import {IUserSettings} from "../settings/IUserSettings.sol";
interface IPoolInternal is IPosition, IPricing {
error Pool__AboveQuoteSize(UD60x18 size, UD60x18 quoteSize);
error Pool__AboveMaxSlippage(uint256 value, uint256 minimum, uint256 maximum);
error Pool__ActionNotAuthorized(address user, address sender, IUserSettings.Action action);
error Pool__AgentNotAuthorized();
error Pool__CostExceedsPayout(UD60x18 cost, UD60x18 payout);
error Pool__CostNotAuthorized(UD60x18 costInWrappedNative, UD60x18 authorizedCost);
error Pool__FlashLoanCallbackFailed();
error Pool__FlashLoanNotRepayed();
error Pool__InsufficientAskLiquidity();
error Pool__InsufficientBidLiquidity();
error Pool__InsufficientFunds();
error Pool__InsufficientLiquidity();
error Pool__InvalidAssetUpdate(SD59x18 deltaLongs, SD59x18 deltaShorts);
error Pool__InvalidBelowPrice(UD60x18 price, UD60x18 priceBelow);
error Pool__InvalidMonth(uint256 month);
error Pool__InvalidPositionState(uint256 balance, uint256 lastDeposit);
error Pool__InvalidQuoteOBSignature();
error Pool__InvalidQuoteOBTaker();
error Pool__InvalidRange(UD60x18 lower, UD60x18 upper);
error Pool__InvalidReconciliation(uint256 crossings);
error Pool__InvalidSize(UD60x18 lower, UD60x18 upper, UD60x18 depositSize);
error Pool__InvalidTickPrice();
error Pool__InvalidTickUpdate();
error Pool__InvalidTransfer();
error Pool__NotEnoughTokens(UD60x18 balance, UD60x18 size);
error Pool__NotPoolToken(address token);
error Pool__NotWrappedNativeTokenPool();
error Pool__OperatorNotAuthorized(address sender);
error Pool__OptionExpired();
error Pool__OptionNotExpired();
error Pool__OutOfBoundsPrice(UD60x18 price);
error Pool__PositionDoesNotExist(address owner, uint256 tokenId);
error Pool__PositionCantHoldLongAndShort(UD60x18 longs, UD60x18 shorts);
error Pool__QuoteOBCancelled();
error Pool__QuoteOBExpired();
error Pool__QuoteOBOverfilled(UD60x18 filledAmount, UD60x18 size, UD60x18 quoteOBSize);
error Pool__SettlementFailed();
error Pool__SettlementPriceAlreadyCached();
error Pool__TickDeltaNotZero(SD59x18 tickDelta);
error Pool__TickNotFound(UD60x18 price);
error Pool__TickOutOfRange(UD60x18 price);
error Pool__TickWidthInvalid(UD60x18 price);
error Pool__WithdrawalDelayNotElapsed(uint256 unlockTime);
error Pool__ZeroSize();
struct Tick {
SD49x28 delta;
UD50x28 externalFeeRate;
SD49x28 longDelta;
SD49x28 shortDelta;
uint256 counter;
}
struct TickWithRates {
Tick tick;
UD60x18 price;
UD50x28 longRate;
UD50x28 shortRate;
}
struct QuoteOB {
address provider;
address taker;
UD60x18 price;
UD60x18 size;
bool isBuy;
uint256 deadline;
uint256 salt;
}
enum InvalidQuoteOBError {
None,
QuoteOBExpired,
QuoteOBCancelled,
QuoteOBOverfilled,
OutOfBoundsPrice,
InvalidQuoteOBTaker,
InvalidQuoteOBSignature,
InvalidAssetUpdate,
InsufficientCollateralAllowance,
InsufficientCollateralBalance,
InsufficientLongBalance,
InsufficientShortBalance
}
struct TradeArgsInternal {
address user;
address referrer;
UD60x18 size;
bool isBuy;
uint256 premiumLimit;
bool transferCollateralToUser;
}
struct ReferralVarsInternal {
UD60x18 totalRebate;
UD60x18 primaryRebate;
UD60x18 secondaryRebate;
}
struct TradeVarsInternal {
UD60x18 maxSize;
UD60x18 tradeSize;
UD50x28 oldMarketPrice;
UD60x18 totalPremium;
UD60x18 totalTakerFees;
UD60x18 totalProtocolFees;
UD50x28 longDelta;
UD50x28 shortDelta;
ReferralVarsInternal referral;
}
struct DepositArgsInternal {
UD60x18 belowLower;
UD60x18 belowUpper;
UD60x18 size;
UD60x18 minMarketPrice;
UD60x18 maxMarketPrice;
}
struct WithdrawVarsInternal {
bytes32 pKeyHash;
uint256 tokenId;
UD60x18 initialSize;
UD50x28 liquidityPerTick;
bool isFullWithdrawal;
SD49x28 tickDelta;
}
struct Signature {
uint8 v;
bytes32 r;
bytes32 s;
}
struct FillQuoteOBArgsInternal {
address user;
address referrer;
UD60x18 size;
Signature signature;
bool transferCollateralToUser;
}
struct PremiumAndFeeInternal {
UD60x18 totalReferralRebate;
UD60x18 premium;
UD60x18 protocolFee;
UD60x18 premiumTaker;
UD60x18 premiumMaker;
ReferralVarsInternal referral;
}
struct QuoteAMMVarsInternal {
UD60x18 liquidity;
UD60x18 maxSize;
UD60x18 totalPremium;
UD60x18 totalTakerFee;
}
struct SettlePositionVarsInternal {
bytes32 pKeyHash;
uint256 tokenId;
UD60x18 size;
UD60x18 claimableFees;
UD60x18 payoff;
UD60x18 collateral;
}
}
文件 27 的 46:IPosition.sol
pragma solidity ^0.8.19;
import {SD59x18} from "lib/prb-math/src/SD59x18.sol";
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
interface IPosition {
error Position__InvalidOrderType();
error Position__InvalidPositionUpdate(UD60x18 currentBalance, SD59x18 amount);
error Position__LowerGreaterOrEqualUpper(UD60x18 lower, UD60x18 upper);
}
文件 28 的 46:IPricing.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
interface IPricing {
error Pricing__PriceCannotBeComputedWithinTickRange();
error Pricing__PriceOutOfRange(UD60x18 lower, UD60x18 upper, UD60x18 marketPrice);
error Pricing__UpperNotGreaterThanLower(UD60x18 lower, UD60x18 upper);
}
文件 29 的 46:IProxy.sol
pragma solidity ^0.8.8;
interface IProxy {
error Proxy__ImplementationIsNotContract();
fallback() external payable;
}
文件 30 的 46:IUserSettings.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {IMulticall} from "@solidstate/contracts/utils/IMulticall.sol";
interface IUserSettings is IMulticall {
enum Action {
__,
Annihilate,
Exercise,
Settle,
SettlePosition,
WriteFrom
}
error UserSettings__InvalidAction();
error UserSettings__InvalidArrayLength();
event ActionAuthorizationUpdated(
address indexed user,
address indexed operator,
Action[] actions,
bool[] authorization
);
event AuthorizedCostUpdated(address indexed user, UD60x18 amount);
function isActionAuthorized(address user, address operator, Action action) external view returns (bool);
function getActionAuthorization(
address user,
address operator
) external view returns (Action[] memory actions, bool[] memory authorization);
function setActionAuthorization(address operator, Action[] memory actions, bool[] memory authorization) external;
function getAuthorizedCost(address user) external view returns (UD60x18);
function setAuthorizedCost(UD60x18 amount) external;
}
文件 31 的 46:Math.sol
pragma solidity ^0.8.8;
library Math {
function abs(int256 a) internal pure returns (uint256) {
return uint256(a < 0 ? -a : a);
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? b : a;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
unchecked {
return (a & b) + ((a ^ b) >> 1);
}
}
function sqrt(uint256 x) internal pure returns (uint256 y) {
uint256 z = (x + 1) >> 1;
y = x;
while (z < y) {
y = z;
z = (x / z + z) >> 1;
}
}
}
文件 32 的 46: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;
}
}
文件 33 的 46:OwnableStorage.sol
pragma solidity ^0.8.8;
library OwnableStorage {
struct Layout {
address owner;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.Ownable');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
文件 34 的 46:PRBMathExtra.sol
pragma solidity ^0.8.19;
import {UD60x18, ud} from "lib/prb-math/src/UD60x18.sol";
import {SD59x18} from "lib/prb-math/src/SD59x18.sol";
import {UD50x28, uMAX_UD50x28, ud50x28} from "./UD50x28.sol";
import {SD49x28, uMAX_SD49x28} from "./SD49x28.sol";
import {iZERO, SD49_ZERO} from "./Constants.sol";
library PRBMathExtra {
error SD59x18_IntoSD49x28_Overflow(SD59x18 x);
error UD60x18_IntoUD50x28_Overflow(UD60x18 x);
function intoSD49x28(SD59x18 x) internal pure returns (SD49x28 result) {
int256 xUint = x.unwrap() * int256(1e10);
if (xUint > uMAX_SD49x28) revert SD59x18_IntoSD49x28_Overflow(x);
result = SD49x28.wrap(xUint);
}
function intoUD50x28(UD60x18 x) internal pure returns (UD50x28 result) {
uint256 xUint = x.unwrap() * 1e10;
if (xUint > uMAX_UD50x28) revert UD60x18_IntoUD50x28_Overflow(x);
result = UD50x28.wrap(xUint);
}
function max(UD60x18 a, UD60x18 b) internal pure returns (UD60x18) {
return a > b ? a : b;
}
function min(UD60x18 a, UD60x18 b) internal pure returns (UD60x18) {
return a > b ? b : a;
}
function max(SD59x18 a, SD59x18 b) internal pure returns (SD59x18) {
return a > b ? a : b;
}
function min(SD59x18 a, SD59x18 b) internal pure returns (SD59x18) {
return a > b ? b : a;
}
function add(UD60x18 a, SD59x18 b) internal pure returns (UD60x18) {
return b < iZERO ? sub(a, -b) : a + b.intoUD60x18();
}
function sub(UD60x18 a, SD59x18 b) internal pure returns (UD60x18) {
return b < iZERO ? add(a, -b) : a - b.intoUD60x18();
}
function max(UD50x28 a, UD50x28 b) internal pure returns (UD50x28) {
return a > b ? a : b;
}
function min(UD50x28 a, UD50x28 b) internal pure returns (UD50x28) {
return a > b ? b : a;
}
function max(SD49x28 a, SD49x28 b) internal pure returns (SD49x28) {
return a > b ? a : b;
}
function min(SD49x28 a, SD49x28 b) internal pure returns (SD49x28) {
return a > b ? b : a;
}
function add(UD50x28 a, SD49x28 b) internal pure returns (UD50x28) {
return b < SD49_ZERO ? sub(a, -b) : a + b.intoUD50x28();
}
function sub(UD50x28 a, SD49x28 b) internal pure returns (UD50x28) {
return b < SD49_ZERO ? add(a, -b) : a - b.intoUD50x28();
}
function roundToNearestUD60x18(UD50x28 value) internal pure returns (UD60x18 result) {
result = value.intoUD60x18();
if (value - intoUD50x28(result) >= ud50x28(5e9)) {
result = result + ud(1);
}
}
}
文件 35 的 46:PoolProxy.sol
pragma solidity =0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {OwnableStorage} from "@solidstate/contracts/access/ownable/OwnableStorage.sol";
import {IERC1155} from "@solidstate/contracts/interfaces/IERC1155.sol";
import {IERC165} from "@solidstate/contracts/interfaces/IERC165.sol";
import {ERC165BaseInternal} from "@solidstate/contracts/introspection/ERC165/base/ERC165BaseInternal.sol";
import {Proxy} from "@solidstate/contracts/proxy/Proxy.sol";
import {IDiamondReadable} from "@solidstate/contracts/proxy/diamond/readable/IDiamondReadable.sol";
import {IERC20Metadata} from "@solidstate/contracts/token/ERC20/metadata/IERC20Metadata.sol";
import {DoublyLinkedListUD60x18, DoublyLinkedList} from "../libraries/DoublyLinkedListUD60x18.sol";
import {PRBMathExtra} from "../libraries/PRBMathExtra.sol";
import {PoolStorage} from "./PoolStorage.sol";
contract PoolProxy is Proxy, ERC165BaseInternal {
using DoublyLinkedListUD60x18 for DoublyLinkedList.Bytes32List;
using PoolStorage for PoolStorage.Layout;
using PRBMathExtra for UD60x18;
address private immutable DIAMOND;
constructor(
address diamond,
address base,
address quote,
address oracleAdapter,
UD60x18 strike,
uint256 maturity,
bool isCallPool
) {
DIAMOND = diamond;
OwnableStorage.layout().owner = msg.sender;
{
PoolStorage.Layout storage l = PoolStorage.layout();
l.base = base;
l.quote = quote;
l.oracleAdapter = oracleAdapter;
l.strike = strike;
l.maturity = maturity;
uint8 baseDecimals = IERC20Metadata(base).decimals();
uint8 quoteDecimals = IERC20Metadata(quote).decimals();
l.baseDecimals = baseDecimals;
l.quoteDecimals = quoteDecimals;
l.isCallPool = isCallPool;
l.tickIndex.push(PoolStorage.MIN_TICK_PRICE);
l.tickIndex.push(PoolStorage.MAX_TICK_PRICE);
l.currentTick = PoolStorage.MIN_TICK_PRICE;
l.marketPrice = PoolStorage.MIN_TICK_PRICE.intoUD50x28();
}
_setSupportsInterface(type(IERC165).interfaceId, true);
_setSupportsInterface(type(IERC1155).interfaceId, true);
}
function _getImplementation() internal view override returns (address) {
return IDiamondReadable(DIAMOND).facetAddress(msg.sig);
}
}
文件 36 的 46:PoolStorage.sol
pragma solidity ^0.8.19;
import {UD60x18, ud} from "lib/prb-math/src/UD60x18.sol";
import {SD59x18, sd} from "lib/prb-math/src/SD59x18.sol";
import {IERC20} from "@solidstate/contracts/interfaces/IERC20.sol";
import {SafeERC20} from "@solidstate/contracts/utils/SafeERC20.sol";
import {DoublyLinkedList} from "@solidstate/contracts/data/DoublyLinkedList.sol";
import {EnumerableSet} from "@solidstate/contracts/data/EnumerableSet.sol";
import {Position} from "../libraries/Position.sol";
import {OptionMath} from "../libraries/OptionMath.sol";
import {UD50x28} from "../libraries/UD50x28.sol";
import {IERC20Router} from "../router/IERC20Router.sol";
import {IPoolInternal} from "./IPoolInternal.sol";
library PoolStorage {
using SafeERC20 for IERC20;
using PoolStorage for PoolStorage.Layout;
uint256 internal constant SHORT = 0;
uint256 internal constant LONG = 1;
uint8 internal constant TOKEN_VERSION = 1;
UD60x18 internal constant MIN_TICK_DISTANCE = UD60x18.wrap(0.001e18);
UD60x18 internal constant MIN_TICK_PRICE = UD60x18.wrap(0.001e18);
UD60x18 internal constant MAX_TICK_PRICE = UD60x18.wrap(1e18);
bytes32 internal constant STORAGE_SLOT = keccak256("premia.contracts.storage.Pool");
struct Layout {
address base;
address quote;
address oracleAdapter;
uint8 baseDecimals;
uint8 quoteDecimals;
uint256 maturity;
bool isCallPool;
DoublyLinkedList.Bytes32List tickIndex;
mapping(UD60x18 normalizedPrice => IPoolInternal.Tick) ticks;
UD50x28 marketPrice;
UD50x28 globalFeeRate;
UD60x18 protocolFees;
UD60x18 strike;
UD50x28 liquidityRate;
UD50x28 longRate;
UD50x28 shortRate;
UD60x18 currentTick;
UD60x18 settlementPrice;
mapping(bytes32 key => Position.Data) positions;
mapping(address provider => mapping(bytes32 hash => UD60x18 amountFilled)) quoteOBAmountFilled;
bool initFeeDiscountRemoved;
EnumerableSet.UintSet tokenIds;
}
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
function getPoolTokenDecimals(Layout storage l) internal view returns (uint8) {
return l.isCallPool ? l.baseDecimals : l.quoteDecimals;
}
function toPoolTokenDecimals(Layout storage l, uint256 value) internal view returns (uint256) {
uint8 decimals = l.getPoolTokenDecimals();
return OptionMath.scaleDecimals(value, 18, decimals);
}
function toPoolTokenDecimals(Layout storage l, int256 value) internal view returns (int256) {
uint8 decimals = l.getPoolTokenDecimals();
return OptionMath.scaleDecimals(value, 18, decimals);
}
function toPoolTokenDecimals(Layout storage l, UD60x18 value) internal view returns (uint256) {
return l.toPoolTokenDecimals(value.unwrap());
}
function toPoolTokenDecimals(Layout storage l, SD59x18 value) internal view returns (int256) {
return l.toPoolTokenDecimals(value.unwrap());
}
function fromPoolTokenDecimals(Layout storage l, uint256 value) internal view returns (UD60x18) {
uint8 decimals = l.getPoolTokenDecimals();
return ud(OptionMath.scaleDecimals(value, decimals, 18));
}
function fromPoolTokenDecimals(Layout storage l, int256 value) internal view returns (SD59x18) {
uint8 decimals = l.getPoolTokenDecimals();
return sd(OptionMath.scaleDecimals(value, decimals, 18));
}
function getPoolToken(Layout storage l) internal view returns (address) {
return l.isCallPool ? l.base : l.quote;
}
function formatTokenId(
address operator,
UD60x18 lower,
UD60x18 upper,
Position.OrderType orderType
) internal pure returns (uint256 tokenId) {
if (lower >= upper || lower < MIN_TICK_PRICE || upper > MAX_TICK_PRICE)
revert IPoolInternal.Pool__InvalidRange(lower, upper);
tokenId =
(uint256(TOKEN_VERSION) << 252) +
(uint256(orderType) << 180) +
(uint256(uint160(operator)) << 20) +
((upper.unwrap() / MIN_TICK_DISTANCE.unwrap()) << 10) +
(lower.unwrap() / MIN_TICK_DISTANCE.unwrap());
}
function parseTokenId(
uint256 tokenId
)
internal
pure
returns (uint8 version, address operator, UD60x18 lower, UD60x18 upper, Position.OrderType orderType)
{
uint256 minTickDistance = MIN_TICK_DISTANCE.unwrap();
assembly {
version := shr(252, tokenId)
orderType := and(shr(180, tokenId), 0xF)
operator := shr(20, tokenId)
upper := mul(
and(shr(10, tokenId), 0x3FF),
minTickDistance
)
lower := mul(
and(tokenId, 0x3FF),
minTickDistance
)
}
}
function approve(IERC20 token, address spender, UD60x18 value) internal {
token.approve(spender, PoolStorage.layout().toPoolTokenDecimals(value));
}
function safeTransferFrom(IERC20Router router, address token, address from, address to, UD60x18 value) internal {
router.safeTransferFrom(token, from, to, PoolStorage.layout().toPoolTokenDecimals(value));
}
function safeTransferIgnoreDust(IERC20 token, address to, uint256 value) internal {
PoolStorage.Layout storage l = PoolStorage.layout();
uint256 balance = IERC20(l.getPoolToken()).balanceOf(address(this));
if (value == 0) return;
if (balance < value) {
UD60x18 _balance = l.fromPoolTokenDecimals(balance);
UD60x18 _value = l.fromPoolTokenDecimals(value);
UD60x18 relativeDiff = (_value - _balance) / _value;
if (relativeDiff > ud(0.0001 ether)) revert IPoolInternal.Pool__InsufficientFunds();
value = balance;
}
token.safeTransfer(to, value);
}
function safeTransferIgnoreDust(IERC20 token, address to, UD60x18 value) internal {
PoolStorage.Layout storage l = PoolStorage.layout();
safeTransferIgnoreDust(token, to, toPoolTokenDecimals(l, value));
}
}
文件 37 的 46:Position.sol
pragma solidity ^0.8.19;
import {Math} from "@solidstate/contracts/utils/Math.sol";
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {SD59x18, sd} from "lib/prb-math/src/SD59x18.sol";
import {iZERO, ZERO, UD50_ZERO, UD50_ONE, UD50_TWO} from "./Constants.sol";
import {IPosition} from "./IPosition.sol";
import {Pricing} from "./Pricing.sol";
import {UD50x28} from "./UD50x28.sol";
import {SD49x28} from "./SD49x28.sol";
import {PRBMathExtra} from "./PRBMathExtra.sol";
library Position {
using Math for int256;
using Position for Position.Key;
using Position for Position.KeyInternal;
using Position for Position.OrderType;
using PRBMathExtra for UD60x18;
struct Key {
address owner;
address operator;
UD60x18 lower;
UD60x18 upper;
OrderType orderType;
}
struct KeyInternal {
address owner;
address operator;
UD60x18 lower;
UD60x18 upper;
OrderType orderType;
bool isCall;
UD60x18 strike;
}
enum OrderType {
CSUP,
CS,
LC
}
struct Data {
SD49x28 lastFeeRate;
UD60x18 claimableFees;
uint256 lastDeposit;
}
struct Delta {
SD59x18 collateral;
SD59x18 longs;
SD59x18 shorts;
}
function keyHash(Key memory self) internal pure returns (bytes32) {
return keccak256(abi.encode(self.owner, self.operator, self.lower, self.upper, self.orderType));
}
function keyHash(KeyInternal memory self) internal pure returns (bytes32) {
return
keyHash(
Key({
owner: self.owner,
operator: self.operator,
lower: self.lower,
upper: self.upper,
orderType: self.orderType
})
);
}
function toKeyInternal(Key memory self, UD60x18 strike, bool isCall) internal pure returns (KeyInternal memory) {
return
KeyInternal({
owner: self.owner,
operator: self.operator,
lower: self.lower,
upper: self.upper,
orderType: self.orderType,
strike: strike,
isCall: isCall
});
}
function isShort(OrderType orderType) internal pure returns (bool) {
return orderType == OrderType.CS || orderType == OrderType.CSUP;
}
function isLong(OrderType orderType) internal pure returns (bool) {
return orderType == OrderType.LC;
}
function pieceWiseLinear(KeyInternal memory self, UD50x28 price) internal pure returns (UD50x28) {
revertIfLowerGreaterOrEqualUpper(self.lower, self.upper);
if (price <= self.lower.intoUD50x28()) return UD50_ZERO;
else if (self.lower.intoUD50x28() < price && price < self.upper.intoUD50x28())
return Pricing.proportion(self.lower, self.upper, price);
else return UD50_ONE;
}
function pieceWiseQuadratic(KeyInternal memory self, UD50x28 price) internal pure returns (UD50x28) {
revertIfLowerGreaterOrEqualUpper(self.lower, self.upper);
UD50x28 lowerUD50 = self.lower.intoUD50x28();
UD50x28 upperUD50 = self.upper.intoUD50x28();
UD50x28 a;
if (price <= lowerUD50) {
return UD50_ZERO;
} else if (lowerUD50 < price && price < upperUD50) {
a = price;
} else {
a = upperUD50;
}
UD50x28 numerator = (a * a - lowerUD50 * lowerUD50);
UD50x28 denominator = UD50_TWO * (upperUD50 - lowerUD50);
return (numerator / denominator);
}
function collateralToContracts(UD60x18 _collateral, UD60x18 strike, bool isCall) internal pure returns (UD60x18) {
return isCall ? _collateral : _collateral / strike;
}
function contractsToCollateral(UD60x18 _contracts, UD60x18 strike, bool isCall) internal pure returns (UD60x18) {
return isCall ? _contracts : _contracts * strike;
}
function collateralToContracts(UD50x28 _collateral, UD60x18 strike, bool isCall) internal pure returns (UD50x28) {
return isCall ? _collateral : _collateral / strike.intoUD50x28();
}
function contractsToCollateral(UD50x28 _contracts, UD60x18 strike, bool isCall) internal pure returns (UD50x28) {
return isCall ? _contracts : _contracts * strike.intoUD50x28();
}
function liquidityPerTick(KeyInternal memory self, UD60x18 size) internal pure returns (UD50x28) {
UD60x18 amountOfTicks = Pricing.amountOfTicksBetween(self.lower, self.upper);
return size.intoUD50x28() / amountOfTicks.intoUD50x28();
}
function bid(KeyInternal memory self, UD60x18 size, UD50x28 price) internal pure returns (UD60x18) {
return
contractsToCollateral(pieceWiseQuadratic(self, price) * size.intoUD50x28(), self.strike, self.isCall)
.intoUD60x18();
}
function collateral(
KeyInternal memory self,
UD60x18 size,
UD50x28 price
) internal pure returns (UD60x18 _collateral) {
UD50x28 nu = pieceWiseLinear(self, price);
if (self.orderType.isShort()) {
_collateral = contractsToCollateral((UD50_ONE - nu) * size.intoUD50x28(), self.strike, self.isCall)
.intoUD60x18();
if (self.orderType == OrderType.CSUP) {
_collateral = _collateral - (self.bid(size, self.upper.intoUD50x28()) - self.bid(size, price));
} else {
_collateral = _collateral + self.bid(size, price);
}
} else if (self.orderType.isLong()) {
_collateral = self.bid(size, price);
} else {
revert IPosition.Position__InvalidOrderType();
}
}
function contracts(KeyInternal memory self, UD60x18 size, UD50x28 price) internal pure returns (UD60x18) {
UD50x28 nu = pieceWiseLinear(self, price);
if (self.orderType.isLong()) {
return ((UD50_ONE - nu) * size.intoUD50x28()).intoUD60x18();
}
return (nu * size.intoUD50x28()).intoUD60x18();
}
function long(KeyInternal memory self, UD60x18 size, UD50x28 price) internal pure returns (UD60x18) {
if (self.orderType.isShort()) {
return ZERO;
} else if (self.orderType.isLong()) {
return self.contracts(size, price);
} else {
revert IPosition.Position__InvalidOrderType();
}
}
function short(KeyInternal memory self, UD60x18 size, UD50x28 price) internal pure returns (UD60x18) {
if (self.orderType.isShort()) {
return self.contracts(size, price);
} else if (self.orderType.isLong()) {
return ZERO;
} else {
revert IPosition.Position__InvalidOrderType();
}
}
function calculatePositionUpdate(
KeyInternal memory self,
UD60x18 currentBalance,
SD59x18 amount,
UD50x28 price
) internal pure returns (Delta memory delta) {
if (currentBalance.intoSD59x18() + amount < iZERO)
revert IPosition.Position__InvalidPositionUpdate(currentBalance, amount);
UD60x18 absChangeTokens = amount.abs().intoUD60x18();
SD59x18 sign = amount > iZERO ? sd(1e18) : sd(-1e18);
delta.collateral = sign * (self.collateral(absChangeTokens, price)).intoSD59x18();
delta.longs = sign * (self.long(absChangeTokens, price)).intoSD59x18();
delta.shorts = sign * (self.short(absChangeTokens, price)).intoSD59x18();
}
function revertIfLowerGreaterOrEqualUpper(UD60x18 lower, UD60x18 upper) internal pure {
if (lower >= upper) revert IPosition.Position__LowerGreaterOrEqualUpper(lower, upper);
}
}
文件 38 的 46:Pricing.sol
pragma solidity ^0.8.19;
import {UD60x18} from "lib/prb-math/src/UD60x18.sol";
import {DoublyLinkedListUD60x18, DoublyLinkedList} from "../libraries/DoublyLinkedListUD60x18.sol";
import {UD50x28} from "../libraries/UD50x28.sol";
import {PoolStorage} from "../pool/PoolStorage.sol";
import {PRBMathExtra} from "./PRBMathExtra.sol";
import {IPricing} from "./IPricing.sol";
import {ZERO, UD50_ONE} from "./Constants.sol";
library Pricing {
using DoublyLinkedListUD60x18 for DoublyLinkedList.Bytes32List;
using PoolStorage for PoolStorage.Layout;
using PRBMathExtra for UD60x18;
using PRBMathExtra for UD50x28;
struct Args {
UD50x28 liquidityRate;
UD50x28 marketPrice;
UD60x18 lower;
UD60x18 upper;
bool isBuy;
}
function proportion(UD60x18 lower, UD60x18 upper, UD50x28 marketPrice) internal pure returns (UD50x28) {
UD60x18 marketPriceUD60 = marketPrice.intoUD60x18();
if (lower >= upper) revert IPricing.Pricing__UpperNotGreaterThanLower(lower, upper);
if (lower > marketPriceUD60 || marketPriceUD60 > upper)
revert IPricing.Pricing__PriceOutOfRange(lower, upper, marketPriceUD60);
return (marketPrice - lower.intoUD50x28()) / (upper - lower).intoUD50x28();
}
function proportion(Args memory args) internal pure returns (UD50x28) {
return proportion(args.lower, args.upper, args.marketPrice);
}
function amountOfTicksBetween(UD60x18 lower, UD60x18 upper) internal pure returns (UD60x18) {
if (lower >= upper) revert IPricing.Pricing__UpperNotGreaterThanLower(lower, upper);
return (upper - lower) / PoolStorage.MIN_TICK_DISTANCE;
}
function amountOfTicksBetween(Args memory args) internal pure returns (UD60x18) {
return amountOfTicksBetween(args.lower, args.upper);
}
function liquidity(Args memory args) internal pure returns (UD60x18) {
return (args.liquidityRate * amountOfTicksBetween(args).intoUD50x28()).intoUD60x18();
}
function bidLiquidity(Args memory args) internal pure returns (UD60x18) {
return (proportion(args) * liquidity(args).intoUD50x28()).roundToNearestUD60x18();
}
function askLiquidity(Args memory args) internal pure returns (UD60x18) {
return ((UD50_ONE - proportion(args)) * liquidity(args).intoUD50x28()).roundToNearestUD60x18();
}
function maxTradeSize(Args memory args) internal pure returns (UD60x18) {
return args.isBuy ? askLiquidity(args) : bidLiquidity(args);
}
function price(Args memory args, UD60x18 tradeSize) internal pure returns (UD50x28) {
UD60x18 liq = liquidity(args);
if (liq == ZERO) return (args.isBuy ? args.upper : args.lower).intoUD50x28();
UD50x28 _proportion;
if (tradeSize > ZERO) _proportion = tradeSize.intoUD50x28() / liq.intoUD50x28();
if (_proportion > UD50_ONE) revert IPricing.Pricing__PriceCannotBeComputedWithinTickRange();
return
args.isBuy
? args.lower.intoUD50x28() + (args.upper - args.lower).intoUD50x28() * _proportion
: args.upper.intoUD50x28() - (args.upper - args.lower).intoUD50x28() * _proportion;
}
function nextPrice(Args memory args, UD60x18 tradeSize) internal pure returns (UD50x28) {
UD60x18 offset = args.isBuy ? bidLiquidity(args) : askLiquidity(args);
return price(args, offset + tradeSize);
}
}
文件 39 的 46: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);
}
文件 40 的 46: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;
文件 41 的 46: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";
文件 42 的 46:SafeERC20.sol
pragma solidity ^0.8.8;
import { IERC20 } from '../interfaces/IERC20.sol';
import { AddressUtils } from './AddressUtils.sol';
library SafeERC20 {
using AddressUtils for address;
error SafeERC20__ApproveFromNonZeroToNonZero();
error SafeERC20__DecreaseAllowanceBelowZero();
error SafeERC20__OperationFailed();
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transfer.selector, to, value)
);
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
);
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
if ((value != 0) && (token.allowance(address(this), spender) != 0))
revert SafeERC20__ApproveFromNonZeroToNonZero();
_callOptionalReturn(
token,
abi.encodeWithSelector(token.approve.selector, spender, value)
);
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
newAllowance
)
);
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
if (oldAllowance < value)
revert SafeERC20__DecreaseAllowanceBelowZero();
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
newAllowance
)
);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(
data,
'SafeERC20: low-level call failed'
);
if (returndata.length > 0) {
if (!abi.decode(returndata, (bool)))
revert SafeERC20__OperationFailed();
}
}
}
文件 43 的 46: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 的 46: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 的 46: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 的 46: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/pool/PoolProxy.sol": "PoolProxy"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"diamond","type":"address"},{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"address","name":"oracleAdapter","type":"address"},{"internalType":"UD60x18","name":"strike","type":"uint256"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"bool","name":"isCallPool","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DoublyLinkedList__InvalidInput","type":"error"},{"inputs":[],"name":"DoublyLinkedList__NonExistentEntry","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[{"internalType":"UD60x18","name":"x","type":"uint256"}],"name":"UD60x18_IntoUD50x28_Overflow","type":"error"},{"stateMutability":"payable","type":"fallback"}]