编译器
0.8.25+commit.b61c2a91
文件 1 的 44:Book.sol
pragma solidity ^0.8.20;
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {IBookManager} from "../interfaces/IBookManager.sol";
import {SegmentedSegmentTree} from "./SegmentedSegmentTree.sol";
import {Tick, TickLibrary} from "./Tick.sol";
import {OrderId, OrderIdLibrary} from "./OrderId.sol";
import {TotalClaimableMap} from "./TotalClaimableMap.sol";
import {TickBitmap} from "./TickBitmap.sol";
library Book {
using Book for State;
using TickBitmap for mapping(uint256 => uint256);
using SegmentedSegmentTree for SegmentedSegmentTree.Core;
using TotalClaimableMap for mapping(uint24 => uint256);
using TickLibrary for Tick;
using OrderIdLibrary for OrderId;
error ZeroUnit();
error BookAlreadyOpened();
error BookNotOpened();
error QueueReplaceFailed();
error CancelFailed(uint64 maxCancelableUnit);
uint40 internal constant MAX_ORDER = 2 ** 15;
uint256 internal constant MAX_ORDER_M = 2 ** 15 - 1;
struct Order {
address provider;
uint64 pending;
}
struct Queue {
SegmentedSegmentTree.Core tree;
Order[] orders;
}
struct State {
IBookManager.BookKey key;
mapping(Tick tick => Queue) queues;
mapping(uint256 => uint256) tickBitmap;
mapping(uint24 groupIndex => uint256) totalClaimableOf;
}
function open(State storage self, IBookManager.BookKey calldata key) external {
if (self.isOpened()) revert BookAlreadyOpened();
self.key = key;
}
function isOpened(State storage self) internal view returns (bool) {
return self.key.unitSize != 0;
}
function checkOpened(State storage self) internal view {
if (!self.isOpened()) revert BookNotOpened();
}
function depth(State storage self, Tick tick) internal view returns (uint64) {
return self.queues[tick].tree.total() - self.totalClaimableOf.get(tick);
}
function highest(State storage self) internal view returns (Tick) {
return self.tickBitmap.highest();
}
function maxLessThan(State storage self, Tick tick) internal view returns (Tick) {
return self.tickBitmap.maxLessThan(tick);
}
function isEmpty(State storage self) internal view returns (bool) {
return self.tickBitmap.isEmpty();
}
function _getOrder(State storage self, Tick tick, uint40 index) private view returns (Order storage) {
return self.queues[tick].orders[index];
}
function getOrder(State storage self, Tick tick, uint40 index) internal view returns (Order memory) {
return _getOrder(self, tick, index);
}
function make(State storage self, Tick tick, uint64 unit, address provider) external returns (uint40 orderIndex) {
if (unit == 0) revert ZeroUnit();
if (!self.tickBitmap.has(tick)) self.tickBitmap.set(tick);
Queue storage queue = self.queues[tick];
orderIndex = SafeCast.toUint40(queue.orders.length);
if (orderIndex >= MAX_ORDER) {
unchecked {
uint40 staleOrderIndex = orderIndex - MAX_ORDER;
uint64 stalePendingUnit = queue.orders[staleOrderIndex].pending;
if (stalePendingUnit > 0) {
uint64 claimable = calculateClaimableUnit(self, tick, staleOrderIndex);
if (claimable != stalePendingUnit) revert QueueReplaceFailed();
}
}
uint64 staleOrderedUnit = queue.tree.get(orderIndex & MAX_ORDER_M);
if (staleOrderedUnit > 0) self.totalClaimableOf.sub(tick, staleOrderedUnit);
}
queue.tree.update(orderIndex & MAX_ORDER_M, unit);
queue.orders.push(Order({pending: unit, provider: provider}));
}
function take(State storage self, Tick tick, uint64 maxTakeUnit) external returns (uint64 takenUnit) {
uint64 currentDepth = depth(self, tick);
if (currentDepth > maxTakeUnit) {
takenUnit = maxTakeUnit;
} else {
takenUnit = currentDepth;
self.tickBitmap.clear(tick);
}
self.totalClaimableOf.add(tick, takenUnit);
}
function cancel(State storage self, OrderId orderId, uint64 to)
external
returns (uint64 canceled, uint64 afterPending)
{
(, Tick tick, uint40 orderIndex) = orderId.decode();
Queue storage queue = self.queues[tick];
uint64 pendingUnit = queue.orders[orderIndex].pending;
uint64 claimableUnit = calculateClaimableUnit(self, tick, orderIndex);
afterPending = to + claimableUnit;
unchecked {
if (pendingUnit < afterPending) revert CancelFailed(pendingUnit - claimableUnit);
canceled = pendingUnit - afterPending;
self.queues[tick].tree.update(
orderIndex & MAX_ORDER_M, self.queues[tick].tree.get(orderIndex & MAX_ORDER_M) - canceled
);
}
queue.orders[orderIndex].pending = afterPending;
if (depth(self, tick) == 0) {
self.tickBitmap.clear(tick);
}
}
function claim(State storage self, Tick tick, uint40 index) external returns (uint64 claimedUnit) {
Order storage order = _getOrder(self, tick, index);
claimedUnit = calculateClaimableUnit(self, tick, index);
unchecked {
order.pending -= claimedUnit;
}
}
function calculateClaimableUnit(State storage self, Tick tick, uint40 index) public view returns (uint64) {
uint64 orderUnit = self.getOrder(tick, index).pending;
Queue storage queue = self.queues[tick];
unchecked {
if (uint256(index) + MAX_ORDER < queue.orders.length) return orderUnit;
uint64 totalClaimableUnit = self.totalClaimableOf.get(tick);
uint64 rangeRight = _getClaimRangeRight(queue, index);
if (rangeRight - orderUnit >= totalClaimableUnit) return 0;
if (rangeRight <= totalClaimableUnit) return orderUnit;
else return totalClaimableUnit - (rangeRight - orderUnit);
}
}
function _getClaimRangeRight(Queue storage queue, uint256 orderIndex) private view returns (uint64 rangeRight) {
uint256 l = queue.orders.length & MAX_ORDER_M;
uint256 r = (orderIndex + 1) & MAX_ORDER_M;
rangeRight = (l < r) ? queue.tree.query(l, r) : queue.tree.total() - queue.tree.query(r, l);
}
}
文件 2 的 44:BookId.sol
pragma solidity ^0.8.20;
import {IBookManager} from "../interfaces/IBookManager.sol";
type BookId is uint192;
library BookIdLibrary {
function toId(IBookManager.BookKey memory bookKey) internal pure returns (BookId id) {
bytes32 hash = keccak256(abi.encode(bookKey));
assembly {
id := and(hash, 0xffffffffffffffffffffffffffffffffffffffffffffffff)
}
}
}
文件 3 的 44:BookManager.sol
pragma solidity ^0.8.20;
import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {IBookManager} from "./interfaces/IBookManager.sol";
import {ILocker} from "./interfaces/ILocker.sol";
import {IHooks} from "./interfaces/IHooks.sol";
import {BookId, BookIdLibrary} from "./libraries/BookId.sol";
import {Book} from "./libraries/Book.sol";
import {Currency, CurrencyLibrary} from "./libraries/Currency.sol";
import {FeePolicy, FeePolicyLibrary} from "./libraries/FeePolicy.sol";
import {Tick, TickLibrary} from "./libraries/Tick.sol";
import {OrderId, OrderIdLibrary} from "./libraries/OrderId.sol";
import {Lockers} from "./libraries/Lockers.sol";
import {CurrencyDelta} from "./libraries/CurrencyDelta.sol";
import {ERC721Permit} from "./libraries/ERC721Permit.sol";
import {Hooks} from "./libraries/Hooks.sol";
contract BookManager is IBookManager, Ownable2Step, ERC721Permit {
using SafeCast for *;
using BookIdLibrary for IBookManager.BookKey;
using TickLibrary for Tick;
using Book for Book.State;
using OrderIdLibrary for OrderId;
using CurrencyLibrary for Currency;
using FeePolicyLibrary for FeePolicy;
using Hooks for IHooks;
string public override baseURI;
string public override contractURI;
address public override defaultProvider;
mapping(Currency currency => uint256) public override reservesOf;
mapping(BookId id => Book.State) internal _books;
mapping(address provider => bool) public override isWhitelisted;
mapping(address provider => mapping(Currency currency => uint256 amount)) public override tokenOwed;
constructor(
address owner_,
address defaultProvider_,
string memory baseURI_,
string memory contractURI_,
string memory name_,
string memory symbol_
) Ownable(owner_) ERC721Permit(name_, symbol_, "2") {
_setDefaultProvider(defaultProvider_);
baseURI = baseURI_;
contractURI = contractURI_;
}
modifier onlyByLocker() {
_checkLocker(msg.sender);
_;
}
function checkAuthorized(address owner, address spender, uint256 tokenId) external view {
_checkAuthorized(owner, spender, tokenId);
}
function _checkLocker(address caller) internal view {
address locker = Lockers.getCurrentLocker();
IHooks hook = Lockers.getCurrentHook();
if (caller == locker) return;
if (caller == address(hook)) return;
revert LockedBy(locker, address(hook));
}
function getBookKey(BookId id) external view returns (BookKey memory) {
return _books[id].key;
}
function getOrder(OrderId id) external view returns (OrderInfo memory) {
(BookId bookId, Tick tick, uint40 orderIndex) = id.decode();
Book.State storage book = _books[bookId];
Book.Order memory order = book.getOrder(tick, orderIndex);
uint64 claimable = book.calculateClaimableUnit(tick, orderIndex);
unchecked {
return OrderInfo({provider: order.provider, open: order.pending - claimable, claimable: claimable});
}
}
function open(BookKey calldata key, bytes calldata hookData) external onlyByLocker {
if (key.unitSize == 0) revert InvalidUnitSize();
FeePolicy makerPolicy = key.makerPolicy;
FeePolicy takerPolicy = key.takerPolicy;
if (!(makerPolicy.isValid() && takerPolicy.isValid())) revert InvalidFeePolicy();
unchecked {
if (makerPolicy.rate() + takerPolicy.rate() < 0) revert InvalidFeePolicy();
}
if (makerPolicy.rate() < 0 || takerPolicy.rate() < 0) {
if (makerPolicy.usesQuote() != takerPolicy.usesQuote()) revert InvalidFeePolicy();
}
IHooks hooks = key.hooks;
if (!hooks.isValidHookAddress()) revert Hooks.HookAddressNotValid(address(hooks));
hooks.beforeOpen(key, hookData);
BookId id = key.toId();
_books[id].open(key);
emit Open(id, key.base, key.quote, key.unitSize, makerPolicy, takerPolicy, hooks);
hooks.afterOpen(key, hookData);
}
function lock(address locker, bytes calldata data) external returns (bytes memory result) {
Lockers.push(locker, msg.sender);
result = ILocker(locker).lockAcquired(msg.sender, data);
Lockers.pop();
(uint128 length, uint128 nonzeroDeltaCount) = Lockers.lockData();
if (length == 0 && nonzeroDeltaCount != 0) revert CurrencyNotSettled();
}
function getCurrencyDelta(address locker, Currency currency) external view returns (int256) {
return CurrencyDelta.get(locker, currency);
}
function getLock(uint256 i) external view returns (address, address) {
return (Lockers.getLocker(i), Lockers.getLockCaller(i));
}
function getLockData() external view returns (uint128, uint128) {
return Lockers.lockData();
}
function getDepth(BookId id, Tick tick) external view returns (uint64) {
return _books[id].depth(tick);
}
function getHighest(BookId id) external view returns (Tick) {
return _books[id].highest();
}
function maxLessThan(BookId id, Tick tick) external view returns (Tick) {
return _books[id].maxLessThan(tick);
}
function isOpened(BookId id) external view returns (bool) {
return _books[id].isOpened();
}
function isEmpty(BookId id) external view returns (bool) {
return _books[id].isEmpty();
}
function encodeBookKey(BookKey calldata key) external pure returns (BookId) {
return key.toId();
}
function make(MakeParams calldata params, bytes calldata hookData)
external
onlyByLocker
returns (OrderId id, uint256 quoteAmount)
{
if (params.provider != address(0) && !isWhitelisted[params.provider]) revert InvalidProvider(params.provider);
params.tick.validateTick();
BookId bookId = params.key.toId();
Book.State storage book = _books[bookId];
book.checkOpened();
params.key.hooks.beforeMake(params, hookData);
uint40 orderIndex = book.make(params.tick, params.unit, params.provider);
id = OrderIdLibrary.encode(bookId, params.tick, orderIndex);
int256 quoteDelta;
unchecked {
quoteAmount = uint256(params.unit) * params.key.unitSize;
quoteDelta = int256(quoteAmount);
if (params.key.makerPolicy.usesQuote()) {
quoteDelta += params.key.makerPolicy.calculateFee(quoteAmount, false);
quoteAmount = uint256(quoteDelta);
}
}
_accountDelta(params.key.quote, -quoteDelta);
_mint(msg.sender, OrderId.unwrap(id));
emit Make(bookId, msg.sender, params.tick, orderIndex, params.unit, params.provider);
params.key.hooks.afterMake(params, id, hookData);
}
function take(TakeParams calldata params, bytes calldata hookData)
external
onlyByLocker
returns (uint256 quoteAmount, uint256 baseAmount)
{
params.tick.validateTick();
BookId bookId = params.key.toId();
Book.State storage book = _books[bookId];
book.checkOpened();
params.key.hooks.beforeTake(params, hookData);
uint64 takenUnit = book.take(params.tick, params.maxUnit);
unchecked {
quoteAmount = uint256(takenUnit) * params.key.unitSize;
}
baseAmount = params.tick.quoteToBase(quoteAmount, true);
int256 quoteDelta = int256(quoteAmount);
int256 baseDelta = baseAmount.toInt256();
if (params.key.takerPolicy.usesQuote()) {
quoteDelta -= params.key.takerPolicy.calculateFee(quoteAmount, false);
quoteAmount = uint256(quoteDelta);
} else {
baseDelta += params.key.takerPolicy.calculateFee(baseAmount, false);
baseAmount = uint256(baseDelta);
}
_accountDelta(params.key.quote, quoteDelta);
_accountDelta(params.key.base, -baseDelta);
emit Take(bookId, msg.sender, params.tick, takenUnit);
params.key.hooks.afterTake(params, takenUnit, hookData);
}
function cancel(CancelParams calldata params, bytes calldata hookData)
external
onlyByLocker
returns (uint256 canceledAmount)
{
_checkAuthorized(_ownerOf(OrderId.unwrap(params.id)), msg.sender, OrderId.unwrap(params.id));
Book.State storage book = _books[params.id.getBookId()];
BookKey memory key = book.key;
key.hooks.beforeCancel(params, hookData);
(uint64 canceledUnit, uint64 pendingUnit) = book.cancel(params.id, params.toUnit);
unchecked {
canceledAmount = uint256(canceledUnit) * key.unitSize;
if (key.makerPolicy.usesQuote()) {
int256 quoteFee = key.makerPolicy.calculateFee(canceledAmount, true);
canceledAmount = uint256(int256(canceledAmount) + quoteFee);
}
}
if (pendingUnit == 0) _burn(OrderId.unwrap(params.id));
_accountDelta(key.quote, int256(canceledAmount));
emit Cancel(params.id, canceledUnit);
key.hooks.afterCancel(params, canceledUnit, hookData);
}
function claim(OrderId id, bytes calldata hookData) external onlyByLocker returns (uint256 claimedAmount) {
_checkAuthorized(_ownerOf(OrderId.unwrap(id)), msg.sender, OrderId.unwrap(id));
Tick tick;
uint40 orderIndex;
Book.State storage book;
{
BookId bookId;
(bookId, tick, orderIndex) = id.decode();
book = _books[bookId];
}
IBookManager.BookKey memory key = book.key;
key.hooks.beforeClaim(id, hookData);
uint64 claimedUnit = book.claim(tick, orderIndex);
int256 quoteFee;
int256 baseFee;
{
uint256 claimedInQuote;
unchecked {
claimedInQuote = uint256(claimedUnit) * key.unitSize;
}
claimedAmount = tick.quoteToBase(claimedInQuote, false);
FeePolicy makerPolicy = key.makerPolicy;
FeePolicy takerPolicy = key.takerPolicy;
if (takerPolicy.usesQuote()) {
quoteFee = takerPolicy.calculateFee(claimedInQuote, true);
} else {
baseFee = takerPolicy.calculateFee(claimedAmount, true);
}
if (makerPolicy.usesQuote()) {
quoteFee += makerPolicy.calculateFee(claimedInQuote, true);
} else {
int256 makeFee = makerPolicy.calculateFee(claimedAmount, false);
baseFee += makeFee;
claimedAmount = makeFee > 0 ? claimedAmount - uint256(makeFee) : claimedAmount + uint256(-makeFee);
}
}
Book.Order memory order = book.getOrder(tick, orderIndex);
address provider = order.provider;
if (provider == address(0)) provider = defaultProvider;
if (quoteFee > 0) tokenOwed[provider][key.quote] += quoteFee.toUint256();
if (baseFee > 0) tokenOwed[provider][key.base] += baseFee.toUint256();
if (order.pending == 0) _burn(OrderId.unwrap(id));
_accountDelta(key.base, claimedAmount.toInt256());
emit Claim(id, claimedUnit);
key.hooks.afterClaim(id, claimedUnit, hookData);
}
function collect(address recipient, Currency currency) external returns (uint256 amount) {
amount = tokenOwed[msg.sender][currency];
tokenOwed[msg.sender][currency] = 0;
reservesOf[currency] -= amount;
currency.transfer(recipient, amount);
emit Collect(msg.sender, recipient, currency, amount);
}
function withdraw(Currency currency, address to, uint256 amount) external onlyByLocker {
if (amount > 0) {
_accountDelta(currency, -amount.toInt256());
reservesOf[currency] -= amount;
currency.transfer(to, amount);
}
}
function settle(Currency currency) external payable onlyByLocker returns (uint256 paid) {
uint256 reservesBefore = reservesOf[currency];
reservesOf[currency] = currency.balanceOfSelf();
paid = reservesOf[currency] - reservesBefore;
_accountDelta(currency, paid.toInt256());
}
function whitelist(address provider) external onlyOwner {
isWhitelisted[provider] = true;
emit Whitelist(provider);
}
function delist(address provider) external onlyOwner {
isWhitelisted[provider] = false;
emit Delist(provider);
}
function setDefaultProvider(address newDefaultProvider) external onlyOwner {
_setDefaultProvider(newDefaultProvider);
}
function _setDefaultProvider(address newDefaultProvider) internal {
defaultProvider = newDefaultProvider;
emit SetDefaultProvider(newDefaultProvider);
}
function _baseURI() internal view override returns (string memory) {
return baseURI;
}
function _accountDelta(Currency currency, int256 delta) internal {
if (delta == 0) return;
address locker = Lockers.getCurrentLocker();
int256 next = CurrencyDelta.add(locker, currency, delta);
if (next == 0) Lockers.decrementNonzeroDeltaCount();
else if (next == delta) Lockers.incrementNonzeroDeltaCount();
}
function load(bytes32 slot) external view returns (bytes32 value) {
assembly {
value := sload(slot)
}
}
function load(bytes32 startSlot, uint256 nSlot) external view returns (bytes memory value) {
value = new bytes(32 * nSlot);
assembly {
for { let i := 0 } lt(i, nSlot) { i := add(i, 1) } {
mstore(add(value, mul(add(i, 1), 32)), sload(add(startSlot, i)))
}
}
}
receive() external payable {}
}
文件 4 的 44:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 5 的 44:Currency.sol
pragma solidity ^0.8.20;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
type Currency is address;
library CurrencyLibrary {
using CurrencyLibrary for Currency;
error NativeTransferFailed();
error ERC20TransferFailed();
Currency public constant NATIVE = Currency.wrap(address(0));
function transfer(Currency currency, address to, uint256 amount) internal {
bool success;
if (currency.isNative()) {
assembly {
success := call(gas(), to, amount, 0, 0, 0, 0)
}
if (!success) revert NativeTransferFailed();
} else {
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(freeMemoryPointer, 36), amount)
success :=
and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), currency, 0, freeMemoryPointer, 68, 0, 32)
)
}
if (!success) revert ERC20TransferFailed();
}
}
function balanceOfSelf(Currency currency) internal view returns (uint256) {
if (currency.isNative()) return address(this).balance;
else return IERC20(Currency.unwrap(currency)).balanceOf(address(this));
}
function equals(Currency currency, Currency other) internal pure returns (bool) {
return Currency.unwrap(currency) == Currency.unwrap(other);
}
function isNative(Currency currency) internal pure returns (bool) {
return Currency.unwrap(currency) == Currency.unwrap(NATIVE);
}
function toId(Currency currency) internal pure returns (uint256) {
return uint160(Currency.unwrap(currency));
}
function fromId(uint256 id) internal pure returns (Currency) {
return Currency.wrap(address(uint160(id)));
}
}
文件 6 的 44:CurrencyDelta.sol
pragma solidity ^0.8.0;
import {Currency, CurrencyLibrary} from "./Currency.sol";
library CurrencyDelta {
uint256 internal constant CURRENCY_DELTA_SLOT = 0x95b400a0305233758f18c75aa62cbbb5d6882951dd55f1407390ee7b6924e26f;
function get(address locker, Currency currency) internal view returns (int256 delta) {
assembly {
mstore(0x14, currency)
mstore(0x00, locker)
delta := tload(keccak256(0x0c, 0x28))
}
}
function add(address locker, Currency currency, int256 delta) internal returns (int256 result) {
assembly {
mstore(0x14, currency)
mstore(0x00, locker)
let slot := keccak256(0x0c, 0x28)
result := add(tload(slot), delta)
tstore(slot, result)
}
}
}
文件 7 的 44:DirtyUint64.sol
pragma solidity ^0.8.0;
library DirtyUint64 {
error DirtyUint64Error(uint256 errorCode);
uint256 private constant _OVERFLOW_ERROR = 0;
uint256 private constant _UNDERFLOW_ERROR = 1;
function toDirtyUnsafe(uint64 cleanUint) internal pure returns (uint64 dirtyUint) {
assembly {
dirtyUint := add(cleanUint, 1)
}
}
function toDirty(uint64 cleanUint) internal pure returns (uint64 dirtyUint) {
assembly {
dirtyUint := add(cleanUint, 1)
}
if (dirtyUint == 0) {
revert DirtyUint64Error(_OVERFLOW_ERROR);
}
}
function toClean(uint64 dirtyUint) internal pure returns (uint64 cleanUint) {
assembly {
cleanUint := sub(dirtyUint, gt(dirtyUint, 0))
}
}
function addClean(uint64 current, uint64 cleanUint) internal pure returns (uint64) {
assembly {
current := add(add(current, iszero(current)), cleanUint)
}
if (current < cleanUint) {
revert DirtyUint64Error(_OVERFLOW_ERROR);
}
return current;
}
function addDirty(uint64 current, uint64 dirtyUint) internal pure returns (uint64) {
assembly {
current := sub(add(add(current, iszero(current)), add(dirtyUint, iszero(dirtyUint))), 1)
}
if (current < dirtyUint) {
revert DirtyUint64Error(_OVERFLOW_ERROR);
}
return current;
}
function subClean(uint64 current, uint64 cleanUint) internal pure returns (uint64 ret) {
assembly {
current := add(current, iszero(current))
ret := sub(current, cleanUint)
}
if (current < ret || ret == 0) {
revert DirtyUint64Error(_UNDERFLOW_ERROR);
}
}
function subDirty(uint64 current, uint64 dirtyUint) internal pure returns (uint64 ret) {
assembly {
current := add(current, iszero(current))
ret := sub(add(current, 1), add(dirtyUint, iszero(dirtyUint)))
}
if (current < ret || ret == 0) {
revert DirtyUint64Error(_UNDERFLOW_ERROR);
}
}
function sumPackedUnsafe(uint256 packed, uint256 from, uint256 to) internal pure returns (uint64 ret) {
packed = packed >> (from << 6);
unchecked {
for (uint256 i = from; i < to; ++i) {
assembly {
let element := and(packed, 0xffffffffffffffff)
ret := add(ret, add(element, iszero(element)))
packed := shr(64, packed)
}
}
}
assembly {
ret := sub(ret, sub(to, from))
}
}
}
文件 8 的 44:ECDSA.sol
pragma solidity ^0.8.20;
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
error ECDSAInvalidSignature();
error ECDSAInvalidSignatureLength(uint256 length);
error ECDSAInvalidSignatureS(bytes32 s);
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError, bytes32) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}
文件 9 的 44:EIP712.sol
pragma solidity ^0.8.20;
import {MessageHashUtils} from "./MessageHashUtils.sol";
import {ShortStrings, ShortString} from "../ShortStrings.sol";
import {IERC5267} from "../../interfaces/IERC5267.sol";
abstract contract EIP712 is IERC5267 {
using ShortStrings for *;
bytes32 private constant TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 private immutable _cachedDomainSeparator;
uint256 private immutable _cachedChainId;
address private immutable _cachedThis;
bytes32 private immutable _hashedName;
bytes32 private immutable _hashedVersion;
ShortString private immutable _name;
ShortString private immutable _version;
string private _nameFallback;
string private _versionFallback;
constructor(string memory name, string memory version) {
_name = name.toShortStringWithFallback(_nameFallback);
_version = version.toShortStringWithFallback(_versionFallback);
_hashedName = keccak256(bytes(name));
_hashedVersion = keccak256(bytes(version));
_cachedChainId = block.chainid;
_cachedDomainSeparator = _buildDomainSeparator();
_cachedThis = address(this);
}
function _domainSeparatorV4() internal view returns (bytes32) {
if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
return _cachedDomainSeparator;
} else {
return _buildDomainSeparator();
}
}
function _buildDomainSeparator() private view returns (bytes32) {
return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
}
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);
}
function eip712Domain()
public
view
virtual
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
)
{
return (
hex"0f",
_EIP712Name(),
_EIP712Version(),
block.chainid,
address(this),
bytes32(0),
new uint256[](0)
);
}
function _EIP712Name() internal view returns (string memory) {
return _name.toStringWithFallback(_nameFallback);
}
function _EIP712Version() internal view returns (string memory) {
return _version.toStringWithFallback(_versionFallback);
}
}
文件 10 的 44:ERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 11 的 44:ERC721.sol
pragma solidity ^0.8.20;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {IERC165, ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {IERC721Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
using Strings for uint256;
string private _name;
string private _symbol;
mapping(address owner => uint256) private _balances;
mapping(uint256 tokenId => address) private _tokenApprovals;
mapping(address owner => mapping(address operator => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId
|| super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual returns (uint256) {
if (owner == address(0)) {
revert ERC721InvalidOwner(address(0));
}
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual returns (address) {
return _requireOwned(tokenId);
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
_requireOwned(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual {
_approve(to, tokenId, _msgSender());
}
function getApproved(uint256 tokenId) public view virtual returns (address) {
_requireOwned(tokenId);
return _getApproved(tokenId);
}
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public virtual {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, _msgSender());
if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
transferFrom(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
function _ownerOf(uint256 tokenId) internal view virtual returns (address);
function _getApproved(uint256 tokenId) internal view virtual returns (address) {
return _tokenApprovals[tokenId];
}
function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
return spender != address(0)
&& (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
}
function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
if (!_isAuthorized(owner, spender, tokenId)) {
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else {
revert ERC721InsufficientApproval(spender, tokenId);
}
}
}
function _increaseBalance(address account, uint128 value) internal virtual {
unchecked {
_balances[account] += value;
}
}
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
address from = _ownerOf(tokenId);
if (auth != address(0)) {
_checkAuthorized(from, auth, tokenId);
}
if (from != address(0)) {
_approve(address(0), tokenId, address(0), false);
unchecked {
_balances[from] -= 1;
}
}
if (to != address(0)) {
unchecked {
_balances[to] += 1;
}
}
_setOwner(tokenId, to);
emit Transfer(from, to, tokenId);
return from;
}
function _mint(address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner != address(0)) {
revert ERC721InvalidSender(address(0));
}
}
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
_mint(to, tokenId);
_checkOnERC721Received(address(0), to, tokenId, data);
}
function _burn(uint256 tokenId) internal {
address previousOwner = _update(address(0), tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
}
function _transfer(address from, address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
function _safeTransfer(address from, address to, uint256 tokenId) internal {
_safeTransfer(from, to, tokenId, "");
}
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
_transfer(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
function _approve(address to, uint256 tokenId, address auth) internal {
_approve(to, tokenId, auth, true);
}
function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
if (emitEvent || auth != address(0)) {
address owner = _requireOwned(tokenId);
if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
revert ERC721InvalidApprover(auth);
}
if (emitEvent) {
emit Approval(owner, to, tokenId);
}
}
_tokenApprovals[tokenId] = to;
}
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC721InvalidOperator(operator);
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _requireOwned(uint256 tokenId) internal view returns (address) {
address owner = _ownerOf(tokenId);
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
return owner;
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
revert ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC721InvalidReceiver(to);
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
function _setOwner(uint256 tokenId, address owner) internal virtual;
}
文件 12 的 44:ERC721Permit.sol
pragma solidity ^0.8.0;
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import {ERC721} from "./ERC721.sol";
import {IERC721Permit} from "../interfaces/IERC721Permit.sol";
contract ERC721Permit is ERC721, IERC721Permit, EIP712 {
bytes32 public constant override PERMIT_TYPEHASH =
0x49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad;
uint256 private constant _NONCE_MASK = uint256(0xffffffffffffffffffffffff) << 160;
mapping(uint256 => uint256) private _nonceAndOwner;
constructor(string memory name_, string memory symbol_, string memory version_)
ERC721(name_, symbol_)
EIP712(name_, version_)
{}
function permit(address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external
override
{
if (block.timestamp > deadline) revert PermitExpired();
bytes32 digest = _hashTypedDataV4(
keccak256(abi.encode(PERMIT_TYPEHASH, spender, tokenId, _getAndIncrementNonce(tokenId), deadline))
);
address owner = ownerOf(tokenId);
if (spender == owner) revert InvalidSignature();
if (owner.code.length > 0) {
if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e) {
revert InvalidSignature();
}
} else {
if (ECDSA.recover(digest, v, r, s) != owner) revert InvalidSignature();
}
_approve(spender, tokenId, owner, true);
}
function DOMAIN_SEPARATOR() public view override returns (bytes32) {
return _domainSeparatorV4();
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
return interfaceId == type(IERC721Permit).interfaceId || super.supportsInterface(interfaceId);
}
function nonces(uint256 id) external view returns (uint256) {
return _nonceAndOwner[id] >> 160;
}
function _getAndIncrementNonce(uint256 tokenId) internal returns (uint256 nonce) {
uint256 nonceAndOwner = _nonceAndOwner[tokenId];
nonce = nonceAndOwner >> 160;
_nonceAndOwner[tokenId] = nonceAndOwner + (1 << 160);
}
function _ownerOf(uint256 tokenId) internal view override returns (address) {
return address(uint160(_nonceAndOwner[tokenId]));
}
function _setOwner(uint256 tokenId, address owner) internal override {
_nonceAndOwner[tokenId] = (_nonceAndOwner[tokenId] & _NONCE_MASK) | uint256(uint160(owner));
}
}
文件 13 的 44:FeePolicy.sol
pragma solidity ^0.8.20;
import {Math} from "./Math.sol";
type FeePolicy is uint24;
library FeePolicyLibrary {
uint256 internal constant RATE_PRECISION = 10 ** 6;
int256 internal constant MAX_FEE_RATE = 500000;
int256 internal constant MIN_FEE_RATE = -500000;
uint256 internal constant RATE_MASK = 0x7fffff;
error InvalidFeePolicy();
function encode(bool usesQuote_, int24 rate_) internal pure returns (FeePolicy feePolicy) {
if (rate_ > MAX_FEE_RATE || rate_ < MIN_FEE_RATE) {
revert InvalidFeePolicy();
}
uint256 mask = usesQuote_ ? 1 << 23 : 0;
assembly {
feePolicy := or(mask, add(and(rate_, 0xffffff), MAX_FEE_RATE))
}
}
function isValid(FeePolicy self) internal pure returns (bool) {
int24 r = rate(self);
return !(r > MAX_FEE_RATE || r < MIN_FEE_RATE);
}
function usesQuote(FeePolicy self) internal pure returns (bool f) {
assembly {
f := shr(23, self)
}
}
function rate(FeePolicy self) internal pure returns (int24 r) {
assembly {
r := sub(and(self, RATE_MASK), MAX_FEE_RATE)
}
}
function calculateFee(FeePolicy self, uint256 amount, bool reverseRounding) internal pure returns (int256 fee) {
int24 r = rate(self);
bool positive = r > 0;
uint256 absRate;
unchecked {
absRate = uint256(uint24(positive ? r : -r));
}
uint256 absFee = Math.divide(amount * absRate, RATE_PRECISION, reverseRounding ? !positive : positive);
fee = positive ? int256(absFee) : -int256(absFee);
}
function calculateOriginalAmount(FeePolicy self, uint256 amount, bool reverseFee)
internal
pure
returns (uint256 originalAmount)
{
int24 r = rate(self);
bool positive = r > 0;
uint256 divider;
assembly {
if reverseFee { r := sub(0, r) }
divider := add(RATE_PRECISION, r)
}
originalAmount = Math.divide(amount * RATE_PRECISION, divider, positive);
}
}
文件 14 的 44:Hooks.sol
pragma solidity ^0.8.20;
import {Lockers} from "./Lockers.sol";
import {IBookManager} from "../interfaces/IBookManager.sol";
import {IHooks} from "../interfaces/IHooks.sol";
import {OrderId} from "../libraries/OrderId.sol";
library Hooks {
using Hooks for IHooks;
uint256 internal constant BEFORE_OPEN_FLAG = 1 << 159;
uint256 internal constant AFTER_OPEN_FLAG = 1 << 158;
uint256 internal constant BEFORE_MAKE_FLAG = 1 << 157;
uint256 internal constant AFTER_MAKE_FLAG = 1 << 156;
uint256 internal constant BEFORE_TAKE_FLAG = 1 << 155;
uint256 internal constant AFTER_TAKE_FLAG = 1 << 154;
uint256 internal constant BEFORE_CANCEL_FLAG = 1 << 153;
uint256 internal constant AFTER_CANCEL_FLAG = 1 << 152;
uint256 internal constant BEFORE_CLAIM_FLAG = 1 << 151;
uint256 internal constant AFTER_CLAIM_FLAG = 1 << 150;
struct Permissions {
bool beforeOpen;
bool afterOpen;
bool beforeMake;
bool afterMake;
bool beforeTake;
bool afterTake;
bool beforeCancel;
bool afterCancel;
bool beforeClaim;
bool afterClaim;
}
error HookAddressNotValid(address hooks);
error InvalidHookResponse();
error FailedHookCall();
function validateHookPermissions(IHooks self, Permissions memory permissions) internal pure {
if (
permissions.beforeOpen != self.hasPermission(BEFORE_OPEN_FLAG)
|| permissions.afterOpen != self.hasPermission(AFTER_OPEN_FLAG)
|| permissions.beforeMake != self.hasPermission(BEFORE_MAKE_FLAG)
|| permissions.afterMake != self.hasPermission(AFTER_MAKE_FLAG)
|| permissions.beforeTake != self.hasPermission(BEFORE_TAKE_FLAG)
|| permissions.afterTake != self.hasPermission(AFTER_TAKE_FLAG)
|| permissions.beforeCancel != self.hasPermission(BEFORE_CANCEL_FLAG)
|| permissions.afterCancel != self.hasPermission(AFTER_CANCEL_FLAG)
|| permissions.beforeClaim != self.hasPermission(BEFORE_CLAIM_FLAG)
|| permissions.afterClaim != self.hasPermission(AFTER_CLAIM_FLAG)
) {
revert HookAddressNotValid(address(self));
}
}
function isValidHookAddress(IHooks hook) internal pure returns (bool) {
return address(hook) == address(0) || uint160(address(hook)) >= AFTER_CLAIM_FLAG;
}
function _callHook(IHooks self, bytes memory data) private returns (bytes4 expectedSelector, bytes4 selector) {
bool set = Lockers.setCurrentHook(self);
assembly {
expectedSelector := mload(add(data, 0x20))
}
(bool success, bytes memory result) = address(self).call(data);
if (!success) _revert(result);
selector = abi.decode(result, (bytes4));
if (set) Lockers.clearCurrentHook();
}
function callHook(IHooks self, bytes memory data) internal {
(bytes4 expectedSelector, bytes4 selector) = _callHook(self, data);
if (selector != expectedSelector) revert InvalidHookResponse();
}
function beforeOpen(IHooks self, IBookManager.BookKey memory key, bytes calldata hookData) internal {
if (self.hasPermission(BEFORE_OPEN_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.beforeOpen.selector, msg.sender, key, hookData));
}
}
function afterOpen(IHooks self, IBookManager.BookKey memory key, bytes calldata hookData) internal {
if (self.hasPermission(AFTER_OPEN_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.afterOpen.selector, msg.sender, key, hookData));
}
}
function beforeMake(IHooks self, IBookManager.MakeParams memory params, bytes calldata hookData) internal {
if (self.hasPermission(BEFORE_MAKE_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.beforeMake.selector, msg.sender, params, hookData));
}
}
function afterMake(IHooks self, IBookManager.MakeParams memory params, OrderId orderId, bytes calldata hookData)
internal
{
if (self.hasPermission(AFTER_MAKE_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.afterMake.selector, msg.sender, params, orderId, hookData));
}
}
function beforeTake(IHooks self, IBookManager.TakeParams memory params, bytes calldata hookData) internal {
if (self.hasPermission(BEFORE_TAKE_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.beforeTake.selector, msg.sender, params, hookData));
}
}
function afterTake(IHooks self, IBookManager.TakeParams memory params, uint64 takenAmount, bytes calldata hookData)
internal
{
if (self.hasPermission(AFTER_TAKE_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.afterTake.selector, msg.sender, params, takenAmount, hookData));
}
}
function beforeCancel(IHooks self, IBookManager.CancelParams calldata params, bytes calldata hookData) internal {
if (self.hasPermission(BEFORE_CANCEL_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.beforeCancel.selector, msg.sender, params, hookData));
}
}
function afterCancel(
IHooks self,
IBookManager.CancelParams calldata params,
uint64 canceledAmount,
bytes calldata hookData
) internal {
if (self.hasPermission(AFTER_CANCEL_FLAG)) {
self.callHook(
abi.encodeWithSelector(IHooks.afterCancel.selector, msg.sender, params, canceledAmount, hookData)
);
}
}
function beforeClaim(IHooks self, OrderId orderId, bytes calldata hookData) internal {
if (self.hasPermission(BEFORE_CLAIM_FLAG)) {
self.callHook(abi.encodeWithSelector(IHooks.beforeClaim.selector, msg.sender, orderId, hookData));
}
}
function afterClaim(IHooks self, OrderId orderId, uint64 claimedAmount, bytes calldata hookData) internal {
if (self.hasPermission(AFTER_CLAIM_FLAG)) {
self.callHook(
abi.encodeWithSelector(IHooks.afterClaim.selector, msg.sender, orderId, claimedAmount, hookData)
);
}
}
function hasPermission(IHooks self, uint256 flag) internal pure returns (bool) {
return uint256(uint160(address(self))) & flag != 0;
}
function _revert(bytes memory result) private pure {
if (result.length == 0) revert FailedHookCall();
assembly {
revert(add(0x20, result), mload(result))
}
}
}
文件 15 的 44:IBookManager.sol
pragma solidity ^0.8.0;
import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import {BookId} from "../libraries/BookId.sol";
import {Currency} from "../libraries/Currency.sol";
import {OrderId} from "../libraries/OrderId.sol";
import {Tick} from "../libraries/Tick.sol";
import {FeePolicy} from "../libraries/FeePolicy.sol";
import {IERC721Permit} from "./IERC721Permit.sol";
import {IHooks} from "./IHooks.sol";
interface IBookManager is IERC721Metadata, IERC721Permit {
error InvalidUnitSize();
error InvalidFeePolicy();
error InvalidProvider(address provider);
error LockedBy(address locker, address hook);
error CurrencyNotSettled();
event Open(
BookId indexed id,
Currency indexed base,
Currency indexed quote,
uint64 unitSize,
FeePolicy makerPolicy,
FeePolicy takerPolicy,
IHooks hooks
);
event Make(
BookId indexed bookId, address indexed user, Tick tick, uint256 orderIndex, uint64 unit, address provider
);
event Take(BookId indexed bookId, address indexed user, Tick tick, uint64 unit);
event Cancel(OrderId indexed orderId, uint64 unit);
event Claim(OrderId indexed orderId, uint64 unit);
event Whitelist(address indexed provider);
event Delist(address indexed provider);
event Collect(address indexed provider, address indexed recipient, Currency indexed currency, uint256 amount);
event SetDefaultProvider(address indexed newDefaultProvider);
struct BookKey {
Currency base;
uint64 unitSize;
Currency quote;
FeePolicy makerPolicy;
IHooks hooks;
FeePolicy takerPolicy;
}
function baseURI() external view returns (string memory);
function contractURI() external view returns (string memory);
function defaultProvider() external view returns (address);
function reservesOf(Currency currency) external view returns (uint256);
function isWhitelisted(address provider) external view returns (bool);
function checkAuthorized(address owner, address spender, uint256 tokenId) external view;
function tokenOwed(address provider, Currency currency) external view returns (uint256);
function getCurrencyDelta(address locker, Currency currency) external view returns (int256);
function getBookKey(BookId id) external view returns (BookKey memory);
struct OrderInfo {
address provider;
uint64 open;
uint64 claimable;
}
function getOrder(OrderId id) external view returns (OrderInfo memory);
function getLock(uint256 i) external view returns (address locker, address lockCaller);
function getLockData() external view returns (uint128, uint128);
function getDepth(BookId id, Tick tick) external view returns (uint64);
function getHighest(BookId id) external view returns (Tick tick);
function maxLessThan(BookId id, Tick tick) external view returns (Tick);
function isOpened(BookId id) external view returns (bool);
function isEmpty(BookId id) external view returns (bool);
function encodeBookKey(BookKey calldata key) external pure returns (BookId);
function load(bytes32 slot) external view returns (bytes32);
function load(bytes32 startSlot, uint256 nSlot) external view returns (bytes memory);
function open(BookKey calldata key, bytes calldata hookData) external;
function lock(address locker, bytes calldata data) external returns (bytes memory);
struct MakeParams {
BookKey key;
Tick tick;
uint64 unit;
address provider;
}
function make(MakeParams calldata params, bytes calldata hookData)
external
returns (OrderId id, uint256 quoteAmount);
struct TakeParams {
BookKey key;
Tick tick;
uint64 maxUnit;
}
function take(TakeParams calldata params, bytes calldata hookData)
external
returns (uint256 quoteAmount, uint256 baseAmount);
struct CancelParams {
OrderId id;
uint64 toUnit;
}
function cancel(CancelParams calldata params, bytes calldata hookData) external returns (uint256 canceledAmount);
function claim(OrderId id, bytes calldata hookData) external returns (uint256 claimedAmount);
function collect(address recipient, Currency currency) external returns (uint256);
function withdraw(Currency currency, address to, uint256 amount) external;
function settle(Currency currency) external payable returns (uint256);
function whitelist(address provider) external;
function delist(address provider) external;
function setDefaultProvider(address newDefaultProvider) external;
}
文件 16 的 44:IERC1271.sol
pragma solidity ^0.8.20;
interface IERC1271 {
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
文件 17 的 44:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 18 的 44:IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 19 的 44:IERC5267.sol
pragma solidity ^0.8.20;
interface IERC5267 {
event EIP712DomainChanged();
function eip712Domain()
external
view
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
}
文件 20 的 44:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 21 的 44:IERC721Metadata.sol
pragma solidity ^0.8.20;
import {IERC721} from "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 22 的 44:IERC721Permit.sol
pragma solidity ^0.8.0;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IERC721Permit is IERC721 {
error InvalidSignature();
error PermitExpired();
function PERMIT_TYPEHASH() external pure returns (bytes32);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function permit(address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
function nonces(uint256 tokenId) external view returns (uint256);
}
文件 23 的 44:IERC721Receiver.sol
pragma solidity ^0.8.20;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 24 的 44:IHooks.sol
pragma solidity ^0.8.20;
import {IBookManager} from "./IBookManager.sol";
import {OrderId} from "../libraries/OrderId.sol";
interface IHooks {
function beforeOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)
external
returns (bytes4);
function afterOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)
external
returns (bytes4);
function beforeMake(address sender, IBookManager.MakeParams calldata params, bytes calldata hookData)
external
returns (bytes4);
function afterMake(
address sender,
IBookManager.MakeParams calldata params,
OrderId orderId,
bytes calldata hookData
) external returns (bytes4);
function beforeTake(address sender, IBookManager.TakeParams calldata params, bytes calldata hookData)
external
returns (bytes4);
function afterTake(
address sender,
IBookManager.TakeParams calldata params,
uint64 takenUnit,
bytes calldata hookData
) external returns (bytes4);
function beforeCancel(address sender, IBookManager.CancelParams calldata params, bytes calldata hookData)
external
returns (bytes4);
function afterCancel(
address sender,
IBookManager.CancelParams calldata params,
uint64 canceledUnit,
bytes calldata hookData
) external returns (bytes4);
function beforeClaim(address sender, OrderId orderId, bytes calldata hookData) external returns (bytes4);
function afterClaim(address sender, OrderId orderId, uint64 claimedUnit, bytes calldata hookData)
external
returns (bytes4);
}
文件 25 的 44:ILocker.sol
pragma solidity ^0.8.0;
interface ILocker {
function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory);
}
文件 26 的 44:Lockers.sol
pragma solidity ^0.8.23;
import {IHooks} from "../interfaces/IHooks.sol";
library Lockers {
uint256 internal constant LOCK_DATA_SLOT = 0x760a9a962ae3d184e99c0483cf5684fb3170f47116ca4f445c50209da4f4f907;
uint256 internal constant LOCKERS_SLOT = 0x722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b1;
uint256 internal constant LOCKER_STRUCT_SIZE = 2;
uint256 internal constant HOOK_ADDRESS_SLOT = 0xfcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422;
uint256 internal constant NONZERO_DELTA_COUNT_OFFSET = 2 ** 128;
uint256 internal constant LENGTH_MASK = (1 << 128) - 1;
function push(address locker, address lockCaller) internal {
assembly {
let data := tload(LOCK_DATA_SLOT)
let l := and(data, LENGTH_MASK)
let indexToWrite := add(LOCKERS_SLOT, mul(l, LOCKER_STRUCT_SIZE))
tstore(indexToWrite, locker)
tstore(add(indexToWrite, 1), lockCaller)
tstore(LOCK_DATA_SLOT, add(data, 1))
}
}
function lockData() internal view returns (uint128 l, uint128 nonzeroDeltaCount) {
assembly {
let data := tload(LOCK_DATA_SLOT)
l := and(data, LENGTH_MASK)
nonzeroDeltaCount := shr(128, data)
}
}
function length() internal view returns (uint128 l) {
assembly {
l := and(tload(LOCK_DATA_SLOT), LENGTH_MASK)
}
}
function pop() internal {
assembly {
let data := tload(LOCK_DATA_SLOT)
let l := and(data, LENGTH_MASK)
if iszero(l) {
mstore(0x00, 0xf1c77ed0)
revert(0x1c, 0x04)
}
let indexToWrite := add(LOCKERS_SLOT, mul(sub(l, 1), LOCKER_STRUCT_SIZE))
tstore(indexToWrite, 0)
tstore(add(indexToWrite, 1), 0)
tstore(LOCK_DATA_SLOT, sub(data, 1))
}
}
function getLocker(uint256 i) internal view returns (address locker) {
assembly {
locker := tload(add(LOCKERS_SLOT, mul(i, LOCKER_STRUCT_SIZE)))
}
}
function getLockCaller(uint256 i) internal view returns (address locker) {
assembly {
locker := tload(add(LOCKERS_SLOT, add(mul(i, LOCKER_STRUCT_SIZE), 1)))
}
}
function getCurrentLocker() internal view returns (address) {
unchecked {
uint256 l = length();
return l > 0 ? getLocker(l - 1) : address(0);
}
}
function getCurrentLockCaller() internal view returns (address) {
unchecked {
uint256 l = length();
return l > 0 ? getLockCaller(l - 1) : address(0);
}
}
function incrementNonzeroDeltaCount() internal {
assembly {
tstore(LOCK_DATA_SLOT, add(tload(LOCK_DATA_SLOT), NONZERO_DELTA_COUNT_OFFSET))
}
}
function decrementNonzeroDeltaCount() internal {
assembly {
tstore(LOCK_DATA_SLOT, sub(tload(LOCK_DATA_SLOT), NONZERO_DELTA_COUNT_OFFSET))
}
}
function getCurrentHook() internal view returns (IHooks currentHook) {
return IHooks(getHook(length()));
}
function getHook(uint256 i) internal view returns (address hook) {
assembly {
hook := tload(add(HOOK_ADDRESS_SLOT, i))
}
}
function setCurrentHook(IHooks currentHook) internal returns (bool set) {
if (address(getCurrentHook()) == address(0)) {
uint256 l = length();
assembly {
tstore(add(HOOK_ADDRESS_SLOT, l), currentHook)
}
return true;
}
}
function clearCurrentHook() internal {
uint256 l = length();
assembly {
tstore(add(HOOK_ADDRESS_SLOT, l), 0)
}
}
}
文件 27 的 44:Math.sol
pragma solidity ^0.8.0;
library Math {
function divide(uint256 a, uint256 b, bool roundingUp) internal pure returns (uint256 ret) {
assembly {
ret := add(div(a, b), and(gt(mod(a, b), 0), roundingUp))
}
}
function lnWad(int256 x) internal pure returns (int256 r) {
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
if iszero(sgt(x, 0)) {
mstore(0x00, 0x1615e638)
revert(0x1c, 0x04)
}
r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))
x := shr(159, shl(r, x))
let p := sub(
sar(96, mul(add(43456485725739037958740375743393,
sar(96, mul(add(24828157081833163892658089445524,
sar(96, mul(add(3273285459638523848632254066296,
x), x))), x))), x)), 11111509109440967052023855526967)
p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)
p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)
p := sub(mul(p, x), shl(96, 795164235651350426258249787498))
let q := add(5573035233440673466300451813936, x)
q := add(71694874799317883764090561454958, sar(96, mul(x, q)))
q := add(283447036172924575727196451306956, sar(96, mul(x, q)))
q := add(401686690394027663651624208769553, sar(96, mul(x, q)))
q := add(204048457590392012362485061816622, sar(96, mul(x, q)))
q := add(31853899698501571402653359427138, sar(96, mul(x, q)))
q := add(909429971244387300277376558375, sar(96, mul(x, q)))
p := sdiv(p, q)
p := mul(1677202110996718588342820967067443963516166, p)
p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)
r := sdiv(p, 302231454903657293676544000000000000000000)
}
}
}
文件 28 的 44:MessageHashUtils.sol
pragma solidity ^0.8.20;
import {Strings} from "../Strings.sol";
library MessageHashUtils {
function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
assembly {
mstore(0x00, "\x19Ethereum Signed Message:\n32")
mstore(0x1c, messageHash)
digest := keccak256(0x00, 0x3c)
}
}
function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
return
keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message));
}
function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(hex"19_00", validator, data));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
assembly {
let ptr := mload(0x40)
mstore(ptr, hex"19_01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
digest := keccak256(ptr, 0x42)
}
}
}
文件 29 的 44:OrderId.sol
pragma solidity ^0.8.0;
import {Tick} from "./Tick.sol";
import {BookId} from "./BookId.sol";
type OrderId is uint256;
library OrderIdLibrary {
function encode(BookId bookId, Tick tick, uint40 index) internal pure returns (OrderId id) {
uint256 _tick = uint256(uint24(Tick.unwrap(tick)));
assembly {
id := add(index, add(shl(40, _tick), shl(64, bookId)))
}
}
function decode(OrderId id) internal pure returns (BookId bookId, Tick tick, uint40 index) {
assembly {
bookId := shr(64, id)
tick := and(shr(40, id), 0xffffff)
index := and(id, 0xffffffffff)
}
}
function getBookId(OrderId id) internal pure returns (BookId bookId) {
assembly {
bookId := shr(64, id)
}
}
function getTick(OrderId id) internal pure returns (Tick tick) {
assembly {
tick := and(shr(40, id), 0xffffff)
}
}
function getIndex(OrderId id) internal pure returns (uint40 index) {
assembly {
index := and(id, 0xffffffffff)
}
}
}
文件 30 的 44:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 31 的 44:Ownable2Step.sol
pragma solidity ^0.8.20;
import {Ownable} from "./Ownable.sol";
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}
文件 32 的 44:PackedUint256.sol
pragma solidity ^0.8.0;
library PackedUint256 {
error PackedUint256Error(uint256 errorCode);
uint256 private constant _UINT8_INDEX_ERROR = 0;
uint256 private constant _UINT16_INDEX_ERROR = 1;
uint256 private constant _UINT32_INDEX_ERROR = 2;
uint256 private constant _UINT64_INDEX_ERROR = 3;
uint256 private constant _MAX_UINT64 = type(uint64).max;
uint256 private constant _MAX_UINT32 = type(uint32).max;
uint256 private constant _MAX_UINT16 = type(uint16).max;
uint256 private constant _MAX_UINT8 = type(uint8).max;
function get8Unsafe(uint256 packed, uint256 index) internal pure returns (uint8 ret) {
assembly {
ret := and(shr(shl(3, index), packed), 0xff)
}
}
function get8(uint256 packed, uint256 index) internal pure returns (uint8 ret) {
if (index > 31) {
revert PackedUint256Error(_UINT8_INDEX_ERROR);
}
assembly {
ret := and(shr(shl(3, index), packed), 0xff)
}
}
function get16Unsafe(uint256 packed, uint256 index) internal pure returns (uint16 ret) {
assembly {
ret := and(shr(shl(4, index), packed), 0xffff)
}
}
function get16(uint256 packed, uint256 index) internal pure returns (uint16 ret) {
if (index > 15) {
revert PackedUint256Error(_UINT16_INDEX_ERROR);
}
assembly {
ret := and(shr(shl(4, index), packed), 0xffff)
}
}
function get32Unsafe(uint256 packed, uint256 index) internal pure returns (uint32 ret) {
assembly {
ret := and(shr(shl(5, index), packed), 0xffffffff)
}
}
function get32(uint256 packed, uint256 index) internal pure returns (uint32 ret) {
if (index > 7) {
revert PackedUint256Error(_UINT32_INDEX_ERROR);
}
assembly {
ret := and(shr(shl(5, index), packed), 0xffffffff)
}
}
function get64Unsafe(uint256 packed, uint256 index) internal pure returns (uint64 ret) {
assembly {
ret := and(shr(shl(6, index), packed), 0xffffffffffffffff)
}
}
function get64(uint256 packed, uint256 index) internal pure returns (uint64 ret) {
if (index > 3) {
revert PackedUint256Error(_UINT64_INDEX_ERROR);
}
assembly {
ret := and(shr(shl(6, index), packed), 0xffffffffffffffff)
}
}
function add8Unsafe(uint256 packed, uint256 index, uint8 value) internal pure returns (uint256 ret) {
assembly {
ret := add(packed, shl(shl(3, index), and(value, 0xff)))
}
}
function add8(uint256 packed, uint256 index, uint8 value) internal pure returns (uint256 ret) {
if (index > 31) {
revert PackedUint256Error(_UINT8_INDEX_ERROR);
}
uint8 current = get8Unsafe(packed, index);
current += value;
ret = update8Unsafe(packed, index, current);
}
function add16Unsafe(uint256 packed, uint256 index, uint16 value) internal pure returns (uint256 ret) {
assembly {
ret := add(packed, shl(shl(4, index), and(value, 0xffff)))
}
}
function add16(uint256 packed, uint256 index, uint16 value) internal pure returns (uint256 ret) {
if (index > 15) {
revert PackedUint256Error(_UINT16_INDEX_ERROR);
}
uint16 current = get16Unsafe(packed, index);
current += value;
ret = update16Unsafe(packed, index, current);
}
function add32Unsafe(uint256 packed, uint256 index, uint32 value) internal pure returns (uint256 ret) {
assembly {
ret := add(packed, shl(shl(5, index), and(value, 0xffffffff)))
}
}
function add32(uint256 packed, uint256 index, uint32 value) internal pure returns (uint256 ret) {
if (index > 7) {
revert PackedUint256Error(_UINT32_INDEX_ERROR);
}
uint32 current = get32Unsafe(packed, index);
current += value;
ret = update32Unsafe(packed, index, current);
}
function add64Unsafe(uint256 packed, uint256 index, uint64 value) internal pure returns (uint256 ret) {
assembly {
ret := add(packed, shl(shl(6, index), and(value, 0xffffffffffffffff)))
}
}
function add64(uint256 packed, uint256 index, uint64 value) internal pure returns (uint256 ret) {
if (index > 3) {
revert PackedUint256Error(_UINT64_INDEX_ERROR);
}
uint64 current = get64Unsafe(packed, index);
current += value;
ret = update64Unsafe(packed, index, current);
}
function sub8Unsafe(uint256 packed, uint256 index, uint8 value) internal pure returns (uint256 ret) {
assembly {
ret := sub(packed, shl(shl(3, index), and(value, 0xff)))
}
}
function sub8(uint256 packed, uint256 index, uint8 value) internal pure returns (uint256 ret) {
if (index > 31) {
revert PackedUint256Error(_UINT8_INDEX_ERROR);
}
uint8 current = get8Unsafe(packed, index);
current -= value;
ret = update8Unsafe(packed, index, current);
}
function sub16Unsafe(uint256 packed, uint256 index, uint16 value) internal pure returns (uint256 ret) {
assembly {
ret := sub(packed, shl(shl(4, index), and(value, 0xffff)))
}
}
function sub16(uint256 packed, uint256 index, uint16 value) internal pure returns (uint256 ret) {
if (index > 15) {
revert PackedUint256Error(_UINT16_INDEX_ERROR);
}
uint16 current = get16Unsafe(packed, index);
current -= value;
ret = update16Unsafe(packed, index, current);
}
function sub32Unsafe(uint256 packed, uint256 index, uint32 value) internal pure returns (uint256 ret) {
assembly {
ret := sub(packed, shl(shl(5, index), and(value, 0xffffffff)))
}
}
function sub32(uint256 packed, uint256 index, uint32 value) internal pure returns (uint256 ret) {
if (index > 7) {
revert PackedUint256Error(_UINT32_INDEX_ERROR);
}
uint32 current = get32Unsafe(packed, index);
current -= value;
ret = update32Unsafe(packed, index, current);
}
function sub64Unsafe(uint256 packed, uint256 index, uint64 value) internal pure returns (uint256 ret) {
assembly {
ret := sub(packed, shl(shl(6, index), and(value, 0xffffffffffffffff)))
}
}
function sub64(uint256 packed, uint256 index, uint64 value) internal pure returns (uint256 ret) {
if (index > 3) {
revert PackedUint256Error(_UINT64_INDEX_ERROR);
}
uint64 current = get64Unsafe(packed, index);
current -= value;
ret = update64Unsafe(packed, index, current);
}
function update8Unsafe(uint256 packed, uint256 index, uint8 value) internal pure returns (uint256 ret) {
unchecked {
index = index << 3;
packed = packed - (packed & (_MAX_UINT8 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xff)))
}
}
function update8(uint256 packed, uint256 index, uint8 value) internal pure returns (uint256 ret) {
if (index > 31) {
revert PackedUint256Error(_UINT8_INDEX_ERROR);
}
unchecked {
index = index << 3;
packed = packed - (packed & (_MAX_UINT8 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xff)))
}
}
function update16Unsafe(uint256 packed, uint256 index, uint16 value) internal pure returns (uint256 ret) {
unchecked {
index = index << 4;
packed = packed - (packed & (_MAX_UINT16 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xffff)))
}
}
function update16(uint256 packed, uint256 index, uint16 value) internal pure returns (uint256 ret) {
if (index > 15) {
revert PackedUint256Error(_UINT16_INDEX_ERROR);
}
unchecked {
index = index << 4;
packed = packed - (packed & (_MAX_UINT16 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xffff)))
}
}
function update32Unsafe(uint256 packed, uint256 index, uint32 value) internal pure returns (uint256 ret) {
unchecked {
index = index << 5;
packed = packed - (packed & (_MAX_UINT32 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xffffffff)))
}
}
function update32(uint256 packed, uint256 index, uint32 value) internal pure returns (uint256 ret) {
if (index > 7) {
revert PackedUint256Error(_UINT32_INDEX_ERROR);
}
unchecked {
index = index << 5;
packed = packed - (packed & (_MAX_UINT32 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xffffffff)))
}
}
function update64Unsafe(uint256 packed, uint256 index, uint64 value) internal pure returns (uint256 ret) {
unchecked {
index = index << 6;
packed = packed - (packed & (_MAX_UINT64 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xffffffffffffffff)))
}
}
function update64(uint256 packed, uint256 index, uint64 value) internal pure returns (uint256 ret) {
if (index > 3) {
revert PackedUint256Error(_UINT64_INDEX_ERROR);
}
unchecked {
index = index << 6;
packed = packed - (packed & (_MAX_UINT64 << index));
}
assembly {
ret := add(packed, shl(index, and(value, 0xffffffffffffffff)))
}
}
function total32(uint256 packed) internal pure returns (uint256) {
unchecked {
uint256 ret = _MAX_UINT32 & packed;
for (uint256 i = 0; i < 7; ++i) {
packed = packed >> 32;
ret += _MAX_UINT32 & packed;
}
return ret;
}
}
function total64(uint256 packed) internal pure returns (uint256) {
unchecked {
uint256 ret = _MAX_UINT64 & packed;
for (uint256 i = 0; i < 3; ++i) {
packed = packed >> 64;
ret += _MAX_UINT64 & packed;
}
return ret;
}
}
function sum32(uint256 packed, uint256 from, uint256 to) internal pure returns (uint256) {
unchecked {
packed = packed >> (from << 5);
uint256 ret = 0;
for (uint256 i = from; i < to; ++i) {
ret += _MAX_UINT32 & packed;
packed = packed >> 32;
}
return ret;
}
}
function sum64(uint256 packed, uint256 from, uint256 to) internal pure returns (uint256) {
unchecked {
packed = packed >> (from << 6);
uint256 ret = 0;
for (uint256 i = from; i < to; ++i) {
ret += _MAX_UINT64 & packed;
packed = packed >> 64;
}
return ret;
}
}
}
文件 33 的 44:Panic.sol
pragma solidity ^0.8.20;
library Panic {
uint256 internal constant GENERIC = 0x00;
uint256 internal constant ASSERT = 0x01;
uint256 internal constant UNDER_OVERFLOW = 0x11;
uint256 internal constant DIVISION_BY_ZERO = 0x12;
uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
uint256 internal constant EMPTY_ARRAY_POP = 0x31;
uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
uint256 internal constant RESOURCE_ERROR = 0x41;
uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
function panic(uint256 code) internal pure {
assembly {
mstore(0x00, 0x4e487b71)
mstore(0x20, code)
revert(0x1c, 0x24)
}
}
}
文件 34 的 44:SafeCast.sol
pragma solidity ^0.8.20;
library SafeCast {
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
error SafeCastOverflowedIntToUint(int256 value);
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
error SafeCastOverflowedUintToInt(uint256 value);
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
function toInt256(uint256 value) internal pure returns (int256) {
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
function toUint(bool b) internal pure returns (uint256 u) {
assembly {
u := iszero(iszero(b))
}
}
}
文件 35 的 44:SegmentedSegmentTree.sol
pragma solidity ^0.8.0;
import "./PackedUint256.sol";
import "./DirtyUint64.sol";
library SegmentedSegmentTree {
using PackedUint256 for uint256;
using DirtyUint64 for uint64;
error SegmentedSegmentTreeError(uint256 errorCode);
uint256 private constant _INDEX_ERROR = 0;
uint256 private constant _OVERFLOW_ERROR = 1;
uint8 private constant _L = 4;
uint256 private constant _P = 4;
uint256 private constant _P_M = 3;
uint256 private constant _P_P = 2;
uint256 private constant _N_P = 4;
uint256 private constant _MAX_NODES = 2 ** 15;
uint256 private constant _MAX_NODES_P_MINUS_ONE = 14;
struct Core {
mapping(uint256 => uint256)[_L] layers;
}
struct LayerIndex {
uint256 group;
uint256 node;
}
function get(Core storage core, uint256 index) internal view returns (uint64 ret) {
if (index >= _MAX_NODES) {
revert SegmentedSegmentTreeError(_INDEX_ERROR);
}
unchecked {
ret = core.layers[_L - 1][index >> _P_P].get64(index & _P_M).toClean();
}
}
function total(Core storage core) internal view returns (uint64) {
return DirtyUint64.sumPackedUnsafe(core.layers[0][0], 0, _P)
+ DirtyUint64.sumPackedUnsafe(core.layers[0][1], 0, _P);
}
function query(Core storage core, uint256 left, uint256 right) internal view returns (uint64 sum) {
if (left == right) {
return 0;
}
if (left >= right) {
revert SegmentedSegmentTreeError(_INDEX_ERROR);
}
if (right > _MAX_NODES) {
revert SegmentedSegmentTreeError(_INDEX_ERROR);
}
LayerIndex[] memory leftIndices = _getLayerIndices(left);
LayerIndex[] memory rightIndices = _getLayerIndices(right);
uint256 ret;
uint256 deficit;
unchecked {
uint256 leftNodeIndex;
uint256 rightNodeIndex;
for (uint256 l = _L - 1;; --l) {
LayerIndex memory leftIndex = leftIndices[l];
LayerIndex memory rightIndex = rightIndices[l];
leftNodeIndex += leftIndex.node;
rightNodeIndex += rightIndex.node;
if (rightIndex.group == leftIndex.group) {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group], leftNodeIndex, rightNodeIndex);
break;
}
if (rightIndex.group - leftIndex.group < 4) {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group], leftNodeIndex, _P);
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group], 0, rightNodeIndex);
for (uint256 group = leftIndex.group + 1; group < rightIndex.group; group++) {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][group], 0, _P);
}
break;
}
if (leftIndex.group % 4 == 0) {
deficit += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group], 0, leftNodeIndex);
leftNodeIndex = 0;
} else if (leftIndex.group % 4 == 1) {
deficit += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group - 1], 0, _P);
deficit += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group], 0, leftNodeIndex);
leftNodeIndex = 0;
} else if (leftIndex.group % 4 == 2) {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group], leftNodeIndex, _P);
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group + 1], 0, _P);
leftNodeIndex = 1;
} else {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][leftIndex.group], leftNodeIndex, _P);
leftNodeIndex = 1;
}
if (rightIndex.group % 4 == 0) {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group], 0, rightNodeIndex);
rightNodeIndex = 0;
} else if (rightIndex.group % 4 == 1) {
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group - 1], 0, _P);
ret += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group], 0, rightNodeIndex);
rightNodeIndex = 0;
} else if (rightIndex.group % 4 == 2) {
deficit += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group], rightNodeIndex, _P);
deficit += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group + 1], 0, _P);
rightNodeIndex = 1;
} else {
deficit += DirtyUint64.sumPackedUnsafe(core.layers[l][rightIndex.group], rightNodeIndex, _P);
rightNodeIndex = 1;
}
}
ret -= deficit;
}
sum = uint64(ret);
}
function update(Core storage core, uint256 index, uint64 value) internal returns (uint64 replaced) {
if (index >= _MAX_NODES) {
revert SegmentedSegmentTreeError(_INDEX_ERROR);
}
LayerIndex[] memory indices = _getLayerIndices(index);
unchecked {
LayerIndex memory bottomIndex = indices[_L - 1];
replaced = core.layers[_L - 1][bottomIndex.group].get64Unsafe(bottomIndex.node).toClean();
if (replaced >= value) {
uint64 diff = replaced - value;
for (uint256 l = 0; l < _L; ++l) {
LayerIndex memory layerIndex = indices[l];
uint256 node = core.layers[l][layerIndex.group];
core.layers[l][layerIndex.group] =
node.update64(layerIndex.node, node.get64(layerIndex.node).subClean(diff));
}
} else {
uint64 diff = value - replaced;
if (total(core) > type(uint64).max - diff) revert SegmentedSegmentTreeError(_OVERFLOW_ERROR);
for (uint256 l = 0; l < _L; ++l) {
LayerIndex memory layerIndex = indices[l];
uint256 node = core.layers[l][layerIndex.group];
core.layers[l][layerIndex.group] =
node.update64(layerIndex.node, node.get64(layerIndex.node).addClean(diff));
}
}
}
}
function _getLayerIndices(uint256 index) private pure returns (LayerIndex[] memory) {
unchecked {
LayerIndex[] memory indices = new LayerIndex[](_L);
uint256 shifter = _MAX_NODES_P_MINUS_ONE;
for (uint256 l = 0; l < _L; ++l) {
indices[l] = LayerIndex({group: index >> shifter, node: (index >> (shifter - _P_P)) & _P_M});
shifter = shifter - _N_P;
}
return indices;
}
}
}
文件 36 的 44:ShortStrings.sol
pragma solidity ^0.8.20;
import {StorageSlot} from "./StorageSlot.sol";
type ShortString is bytes32;
library ShortStrings {
bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;
error StringTooLong(string str);
error InvalidShortString();
function toShortString(string memory str) internal pure returns (ShortString) {
bytes memory bstr = bytes(str);
if (bstr.length > 31) {
revert StringTooLong(str);
}
return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
}
function toString(ShortString sstr) internal pure returns (string memory) {
uint256 len = byteLength(sstr);
string memory str = new string(32);
assembly {
mstore(str, len)
mstore(add(str, 0x20), sstr)
}
return str;
}
function byteLength(ShortString sstr) internal pure returns (uint256) {
uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
if (result > 31) {
revert InvalidShortString();
}
return result;
}
function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
if (bytes(value).length < 32) {
return toShortString(value);
} else {
StorageSlot.getStringSlot(store).value = value;
return ShortString.wrap(FALLBACK_SENTINEL);
}
}
function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
return toString(value);
} else {
return store;
}
}
function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
return byteLength(value);
} else {
return bytes(store).length;
}
}
}
文件 37 的 44:SignedMath.sol
pragma solidity ^0.8.20;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
int256 mask = n >> 255;
return uint256((n + mask) ^ mask);
}
}
}
文件 38 的 44:SignificantBit.sol
pragma solidity ^0.8.0;
library SignificantBit {
uint256 internal constant DEBRUIJN_SEQ = 0x818283848586878898A8B8C8D8E8F929395969799A9B9D9E9FAAEB6BEDEEFF;
bytes internal constant DEBRUIJN_INDEX =
hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8";
function leastSignificantBit(uint256 x) internal pure returns (uint8) {
require(x > 0);
uint256 index;
assembly {
index := shr(248, mul(and(x, add(not(x), 1)), DEBRUIJN_SEQ))
}
return uint8(DEBRUIJN_INDEX[index]);
}
function mostSignificantBit(uint256 x) internal pure returns (uint8 msb) {
require(x > 0);
assembly {
let f := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
msb := or(msb, f)
x := shr(f, x)
f := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))
msb := or(msb, f)
x := shr(f, x)
f := shl(5, gt(x, 0xFFFFFFFF))
msb := or(msb, f)
x := shr(f, x)
f := shl(4, gt(x, 0xFFFF))
msb := or(msb, f)
x := shr(f, x)
f := shl(3, gt(x, 0xFF))
msb := or(msb, f)
x := shr(f, x)
f := shl(2, gt(x, 0xF))
msb := or(msb, f)
x := shr(f, x)
f := shl(1, gt(x, 0x3))
msb := or(msb, f)
x := shr(f, x)
f := gt(x, 0x1)
msb := or(msb, f)
}
}
}
文件 39 的 44:StorageSlot.sol
pragma solidity ^0.8.24;
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly {
r.slot := slot
}
}
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly {
r.slot := slot
}
}
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly {
r.slot := store.slot
}
}
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly {
r.slot := store.slot
}
}
type AddressSlotType is bytes32;
function asAddress(bytes32 slot) internal pure returns (AddressSlotType) {
return AddressSlotType.wrap(slot);
}
type BooleanSlotType is bytes32;
function asBoolean(bytes32 slot) internal pure returns (BooleanSlotType) {
return BooleanSlotType.wrap(slot);
}
type Bytes32SlotType is bytes32;
function asBytes32(bytes32 slot) internal pure returns (Bytes32SlotType) {
return Bytes32SlotType.wrap(slot);
}
type Uint256SlotType is bytes32;
function asUint256(bytes32 slot) internal pure returns (Uint256SlotType) {
return Uint256SlotType.wrap(slot);
}
type Int256SlotType is bytes32;
function asInt256(bytes32 slot) internal pure returns (Int256SlotType) {
return Int256SlotType.wrap(slot);
}
function tload(AddressSlotType slot) internal view returns (address value) {
assembly {
value := tload(slot)
}
}
function tstore(AddressSlotType slot, address value) internal {
assembly {
tstore(slot, value)
}
}
function tload(BooleanSlotType slot) internal view returns (bool value) {
assembly {
value := tload(slot)
}
}
function tstore(BooleanSlotType slot, bool value) internal {
assembly {
tstore(slot, value)
}
}
function tload(Bytes32SlotType slot) internal view returns (bytes32 value) {
assembly {
value := tload(slot)
}
}
function tstore(Bytes32SlotType slot, bytes32 value) internal {
assembly {
tstore(slot, value)
}
}
function tload(Uint256SlotType slot) internal view returns (uint256 value) {
assembly {
value := tload(slot)
}
}
function tstore(Uint256SlotType slot, uint256 value) internal {
assembly {
tstore(slot, value)
}
}
function tload(Int256SlotType slot) internal view returns (int256 value) {
assembly {
value := tload(slot)
}
}
function tstore(Int256SlotType slot, int256 value) internal {
assembly {
tstore(slot, value)
}
}
}
文件 40 的 44:Strings.sol
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
error StringsInsufficientHexLength(uint256 value, uint256 length);
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 41 的 44:Tick.sol
pragma solidity ^0.8.20;
import {Math} from "./Math.sol";
type Tick is int24;
library TickLibrary {
using Math for *;
using TickLibrary for Tick;
error InvalidTick();
error InvalidPrice();
error TickOverflow();
int24 internal constant MAX_TICK = 2 ** 19 - 1;
int24 internal constant MIN_TICK = -MAX_TICK;
uint256 internal constant MIN_PRICE = 1350587;
uint256 internal constant MAX_PRICE = 4647684107270898330752324302845848816923571339324334;
uint256 private constant _R0 = 0xfff97272373d413259a46990;
uint256 private constant _R1 = 0xfff2e50f5f656932ef12357c;
uint256 private constant _R2 = 0xffe5caca7e10e4e61c3624ea;
uint256 private constant _R3 = 0xffcb9843d60f6159c9db5883;
uint256 private constant _R4 = 0xff973b41fa98c081472e6896;
uint256 private constant _R5 = 0xff2ea16466c96a3843ec78b3;
uint256 private constant _R6 = 0xfe5dee046a99a2a811c461f1;
uint256 private constant _R7 = 0xfcbe86c7900a88aedcffc83b;
uint256 private constant _R8 = 0xf987a7253ac413176f2b074c;
uint256 private constant _R9 = 0xf3392b0822b70005940c7a39;
uint256 private constant _R10 = 0xe7159475a2c29b7443b29c7f;
uint256 private constant _R11 = 0xd097f3bdfd2022b8845ad8f7;
uint256 private constant _R12 = 0xa9f746462d870fdf8a65dc1f;
uint256 private constant _R13 = 0x70d869a156d2a1b890bb3df6;
uint256 private constant _R14 = 0x31be135f97d08fd981231505;
uint256 private constant _R15 = 0x9aa508b5b7a84e1c677de54;
uint256 private constant _R16 = 0x5d6af8dedb81196699c329;
uint256 private constant _R17 = 0x2216e584f5fa1ea92604;
uint256 private constant _R18 = 0x48a170391f7dc42;
uint256 private constant _R19 = 0x149b34;
function validateTick(Tick tick) internal pure {
if (Tick.unwrap(tick) > MAX_TICK || Tick.unwrap(tick) < MIN_TICK) revert InvalidTick();
}
modifier validatePrice(uint256 price) {
if (price > MAX_PRICE || price < MIN_PRICE) revert InvalidPrice();
_;
}
function fromPrice(uint256 price) internal pure validatePrice(price) returns (Tick) {
unchecked {
int24 tick = int24((int256(price).lnWad() * 42951820407860) / 2 ** 128);
if (toPrice(Tick.wrap(tick)) > price) return Tick.wrap(tick - 1);
return Tick.wrap(tick);
}
}
function toPrice(Tick tick) internal pure returns (uint256 price) {
validateTick(tick);
int24 tickValue = Tick.unwrap(tick);
uint256 absTick = uint24(tickValue < 0 ? -tickValue : tickValue);
unchecked {
if (absTick & 0x1 != 0) price = _R0;
else price = 1 << 96;
if (absTick & 0x2 != 0) price = (price * _R1) >> 96;
if (absTick & 0x4 != 0) price = (price * _R2) >> 96;
if (absTick & 0x8 != 0) price = (price * _R3) >> 96;
if (absTick & 0x10 != 0) price = (price * _R4) >> 96;
if (absTick & 0x20 != 0) price = (price * _R5) >> 96;
if (absTick & 0x40 != 0) price = (price * _R6) >> 96;
if (absTick & 0x80 != 0) price = (price * _R7) >> 96;
if (absTick & 0x100 != 0) price = (price * _R8) >> 96;
if (absTick & 0x200 != 0) price = (price * _R9) >> 96;
if (absTick & 0x400 != 0) price = (price * _R10) >> 96;
if (absTick & 0x800 != 0) price = (price * _R11) >> 96;
if (absTick & 0x1000 != 0) price = (price * _R12) >> 96;
if (absTick & 0x2000 != 0) price = (price * _R13) >> 96;
if (absTick & 0x4000 != 0) price = (price * _R14) >> 96;
if (absTick & 0x8000 != 0) price = (price * _R15) >> 96;
if (absTick & 0x10000 != 0) price = (price * _R16) >> 96;
if (absTick & 0x20000 != 0) price = (price * _R17) >> 96;
if (absTick & 0x40000 != 0) price = (price * _R18) >> 96;
}
if (tickValue > 0) price = 0x1000000000000000000000000000000000000000000000000 / price;
}
function gt(Tick a, Tick b) internal pure returns (bool) {
return Tick.unwrap(a) > Tick.unwrap(b);
}
function baseToQuote(Tick tick, uint256 base, bool roundingUp) internal pure returns (uint256) {
return Math.divide((base * tick.toPrice()), 1 << 96, roundingUp);
}
function quoteToBase(Tick tick, uint256 quote, bool roundingUp) internal pure returns (uint256) {
return Math.divide(quote << 96, tick.toPrice(), roundingUp);
}
}
文件 42 的 44:TickBitmap.sol
pragma solidity ^0.8.0;
import {SignificantBit} from "./SignificantBit.sol";
import {Tick} from "./Tick.sol";
library TickBitmap {
using SignificantBit for uint256;
error EmptyError();
error AlreadyExistsError();
uint256 public constant B0_BITMAP_KEY = uint256(keccak256("TickBitmap")) + 1;
uint256 public constant MAX_UINT_256_MINUS_1 = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe;
function has(mapping(uint256 => uint256) storage self, Tick tick) internal view returns (bool) {
(uint256 b0b1, uint256 b2) = _split(tick);
uint256 mask = 1 << b2;
return self[b0b1] & mask == mask;
}
function isEmpty(mapping(uint256 => uint256) storage self) internal view returns (bool) {
return self[B0_BITMAP_KEY] == 0;
}
function _split(Tick tick) private pure returns (uint256 b0b1, uint256 b2) {
assembly {
let value := add(not(tick), 0x800000)
b0b1 := shr(8, and(value, 0xffff00))
b2 := and(value, 0xff)
}
}
function highest(mapping(uint256 => uint256) storage self) internal view returns (Tick) {
if (isEmpty(self)) revert EmptyError();
uint256 b0 = self[B0_BITMAP_KEY].leastSignificantBit();
uint256 b0b1 = (b0 << 8) | (self[~b0].leastSignificantBit());
uint256 b2 = self[b0b1].leastSignificantBit();
return _toTick((b0b1 << 8) | b2);
}
function set(mapping(uint256 => uint256) storage self, Tick tick) internal {
(uint256 b0b1, uint256 b2) = _split(tick);
uint256 mask = 1 << b2;
uint256 b2Bitmap = self[b0b1];
if (b2Bitmap & mask > 0) revert AlreadyExistsError();
self[b0b1] = b2Bitmap | mask;
if (b2Bitmap == 0) {
mask = 1 << (b0b1 & 0xff);
uint256 b1BitmapKey = ~(b0b1 >> 8);
uint256 b1Bitmap = self[b1BitmapKey];
self[b1BitmapKey] = b1Bitmap | mask;
if (b1Bitmap == 0) self[B0_BITMAP_KEY] = self[B0_BITMAP_KEY] | (1 << ~b1BitmapKey);
}
}
function clear(mapping(uint256 => uint256) storage self, Tick tick) internal {
(uint256 b0b1, uint256 b2) = _split(tick);
uint256 mask = 1 << b2;
uint256 b2Bitmap = self[b0b1];
self[b0b1] = b2Bitmap & (~mask);
if (b2Bitmap == mask) {
mask = 1 << (b0b1 & 0xff);
uint256 b1BitmapKey = ~(b0b1 >> 8);
uint256 b1Bitmap = self[b1BitmapKey];
self[b1BitmapKey] = b1Bitmap & (~mask);
if (mask == b1Bitmap) {
mask = 1 << (~b1BitmapKey);
self[B0_BITMAP_KEY] = self[B0_BITMAP_KEY] & (~mask);
}
}
}
function maxLessThan(mapping(uint256 => uint256) storage self, Tick tick) internal view returns (Tick) {
(uint256 b0b1, uint256 b2) = _split(tick);
uint256 b2Bitmap = (MAX_UINT_256_MINUS_1 << b2) & self[b0b1];
if (b2Bitmap == 0) {
uint256 b0 = b0b1 >> 8;
uint256 b1Bitmap = (MAX_UINT_256_MINUS_1 << (b0b1 & 0xff)) & self[~b0];
if (b1Bitmap == 0) {
uint256 b0Bitmap = (MAX_UINT_256_MINUS_1 << b0) & self[B0_BITMAP_KEY];
if (b0Bitmap == 0) return Tick.wrap(type(int24).min);
b0 = b0Bitmap.leastSignificantBit();
b1Bitmap = self[~b0];
}
b0b1 = (b0 << 8) | b1Bitmap.leastSignificantBit();
b2Bitmap = self[b0b1];
}
b2 = b2Bitmap.leastSignificantBit();
return _toTick((b0b1 << 8) | b2);
}
function _toTick(uint256 raw) private pure returns (Tick t) {
assembly {
t := and(not(sub(raw, 0x800000)), 0xffffff)
}
}
}
文件 43 的 44:TotalClaimableMap.sol
pragma solidity ^0.8.20;
import {DirtyUint64} from "./DirtyUint64.sol";
import {PackedUint256} from "./PackedUint256.sol";
import {Tick} from "./Tick.sol";
library TotalClaimableMap {
using DirtyUint64 for uint64;
using PackedUint256 for uint256;
function add(mapping(uint24 => uint256) storage self, Tick tick, uint64 n) internal {
(uint24 groupIndex, uint8 elementIndex) = _splitTick(tick);
uint256 group = self[groupIndex];
self[groupIndex] = group.update64Unsafe(
elementIndex,
group.get64Unsafe(elementIndex).addClean(n)
);
}
function sub(mapping(uint24 => uint256) storage self, Tick tick, uint64 n) internal {
(uint24 groupIndex, uint8 elementIndex) = _splitTick(tick);
self[groupIndex] = self[groupIndex].sub64Unsafe(elementIndex, n);
}
function get(mapping(uint24 => uint256) storage self, Tick tick) internal view returns (uint64) {
(uint24 groupIndex, uint8 elementIndex) = _splitTick(tick);
return self[groupIndex].get64Unsafe(elementIndex).toClean();
}
function _splitTick(Tick tick) internal pure returns (uint24 groupIndex, uint8 elementIndex) {
uint256 casted = uint24(Tick.unwrap(tick));
assembly {
groupIndex := shr(2, casted)
elementIndex := and(casted, 3)
}
}
}
文件 44 的 44:draft-IERC6093.sol
pragma solidity ^0.8.20;
interface IERC20Errors {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
interface IERC721Errors {
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidSender(address sender);
error ERC721InvalidReceiver(address receiver);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721InvalidOperator(address operator);
}
interface IERC1155Errors {
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
error ERC1155InvalidSender(address sender);
error ERC1155InvalidReceiver(address receiver);
error ERC1155MissingApprovalForAll(address operator, address owner);
error ERC1155InvalidApprover(address approver);
error ERC1155InvalidOperator(address operator);
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
{
"compilationTarget": {
"src/BookManager.sol": "BookManager"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"defaultProvider_","type":"address"},{"internalType":"string","name":"baseURI_","type":"string"},{"internalType":"string","name":"contractURI_","type":"string"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BookNotOpened","type":"error"},{"inputs":[],"name":"CurrencyNotSettled","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[],"name":"ERC20TransferFailed","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"EmptyError","type":"error"},{"inputs":[],"name":"FailedHookCall","type":"error"},{"inputs":[{"internalType":"address","name":"hooks","type":"address"}],"name":"HookAddressNotValid","type":"error"},{"inputs":[],"name":"InvalidFeePolicy","type":"error"},{"inputs":[],"name":"InvalidHookResponse","type":"error"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"InvalidProvider","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTick","type":"error"},{"inputs":[],"name":"InvalidUnitSize","type":"error"},{"inputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"address","name":"hook","type":"address"}],"name":"LockedBy","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PermitExpired","type":"error"},{"inputs":[{"internalType":"int256","name":"value","type":"int256"}],"name":"SafeCastOverflowedIntToUint","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintToInt","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"OrderId","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"}],"name":"Cancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"OrderId","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"Currency","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Collect","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"}],"name":"Delist","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"BookId","name":"bookId","type":"uint192"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"Tick","name":"tick","type":"int24"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"},{"indexed":false,"internalType":"address","name":"provider","type":"address"}],"name":"Make","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"BookId","name":"id","type":"uint192"},{"indexed":true,"internalType":"Currency","name":"base","type":"address"},{"indexed":true,"internalType":"Currency","name":"quote","type":"address"},{"indexed":false,"internalType":"uint64","name":"unitSize","type":"uint64"},{"indexed":false,"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"indexed":false,"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"},{"indexed":false,"internalType":"contract IHooks","name":"hooks","type":"address"}],"name":"Open","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newDefaultProvider","type":"address"}],"name":"SetDefaultProvider","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"BookId","name":"bookId","type":"uint192"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"Tick","name":"tick","type":"int24"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"}],"name":"Take","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"}],"name":"Whitelist","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"OrderId","name":"id","type":"uint256"},{"internalType":"uint64","name":"toUnit","type":"uint64"}],"internalType":"struct IBookManager.CancelParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"cancel","outputs":[{"internalType":"uint256","name":"canceledAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"checkAuthorized","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"OrderId","name":"id","type":"uint256"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"claim","outputs":[{"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"Currency","name":"currency","type":"address"}],"name":"collect","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"delist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"}],"name":"encodeBookKey","outputs":[{"internalType":"BookId","name":"","type":"uint192"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"getBookKey","outputs":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"Currency","name":"currency","type":"address"}],"name":"getCurrencyDelta","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"},{"internalType":"Tick","name":"tick","type":"int24"}],"name":"getDepth","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"getHighest","outputs":[{"internalType":"Tick","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"name":"getLock","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLockData","outputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"OrderId","name":"id","type":"uint256"}],"name":"getOrder","outputs":[{"components":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"uint64","name":"open","type":"uint64"},{"internalType":"uint64","name":"claimable","type":"uint64"}],"internalType":"struct IBookManager.OrderInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"isEmpty","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"isOpened","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"load","outputs":[{"internalType":"bytes32","name":"value","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"startSlot","type":"bytes32"},{"internalType":"uint256","name":"nSlot","type":"uint256"}],"name":"load","outputs":[{"internalType":"bytes","name":"value","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"lock","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"},{"internalType":"Tick","name":"tick","type":"int24"},{"internalType":"uint64","name":"unit","type":"uint64"},{"internalType":"address","name":"provider","type":"address"}],"internalType":"struct IBookManager.MakeParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"make","outputs":[{"internalType":"OrderId","name":"id","type":"uint256"},{"internalType":"uint256","name":"quoteAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"},{"internalType":"Tick","name":"tick","type":"int24"}],"name":"maxLessThan","outputs":[{"internalType":"Tick","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Currency","name":"currency","type":"address"}],"name":"reservesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDefaultProvider","type":"address"}],"name":"setDefaultProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Currency","name":"currency","type":"address"}],"name":"settle","outputs":[{"internalType":"uint256","name":"paid","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"},{"internalType":"Tick","name":"tick","type":"int24"},{"internalType":"uint64","name":"maxUnit","type":"uint64"}],"internalType":"struct IBookManager.TakeParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"take","outputs":[{"internalType":"uint256","name":"quoteAmount","type":"uint256"},{"internalType":"uint256","name":"baseAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"Currency","name":"currency","type":"address"}],"name":"tokenOwed","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Currency","name":"currency","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]