编译器
0.8.13+commit.abaa5c0e
文件 1 的 44:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 44:AuxLib.sol
pragma solidity ^0.8.13;
import "./StructsLib.sol";
import "../common/Structs.sol";
import "../common/MathLib.sol";
import "../market/MarketAuxLib.sol";
import "../common/StrippedInterfaces.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
library AuxLib {
using MarketAuxLib for Structs.Asset;
function isShareable(StructsLib.State2 storage state2, address addr) external view returns (bool) {
return state2.assetReg.get(addr).sharable;
}
function isVerified(StructsLib.State2 storage state2, address addr) external view returns (bool) {
return state2.assetReg.get(addr).verified;
}
function isStable(StructsLib.State2 storage state2, address addr) external view returns (bool) {
return state2.assetReg.get(addr).stable;
}
function isStable(IAssetRegistry assetReg, Structs.Market memory m) external view returns (bool) {
return assetReg.get(m.base.addr).stable && assetReg.get(m.quote.addr).stable;
}
function hasOrder(StructsLib.State storage state, uint256 id) public view returns (bool) {
return id < state.orders.length && state.orders[id].marketId != address(0);
}
function canCreateDispute(
StructsLib.State storage state,
StructsLib.State2 storage state2,
uint256 id,
address addr
) public view returns (bool) {
require(hasOrder(state, id), "OC: UNKNOWN_ORDER");
Structs.Order memory o = state.orders[id];
if (state2.marketCore.getMarket(o.marketId).manager != address(0)) return false;
if (o.provider != addr && o.taker != addr) return false;
if (o.released || o.cancelled || !o.paid) return false;
if (o.disputeFrom > block.timestamp) return false;
return true;
}
function isPerm(Structs.Market memory market) public pure returns (bool) {
return market.perms.put || market.perms.swap;
}
function isLiquidityEmpty(Structs.Liquidity memory liq) public pure returns (bool) {
return liq.amount == 0 && liq.ids.length == 0;
}
function isLiquidityExist(StructsLib.State storage state, address mid, address provider, uint256 lid) public view returns (bool) {
return state.liquidity[mid][provider].length > lid;
}
function hasNonZeroLiquidity(StructsLib.State storage state, address mid, address provider, uint256 lid) public view returns (bool) {
if (!isLiquidityExist(state, mid, provider, lid)) return false;
Structs.Liquidity memory liq = state.liquidity[mid][provider][lid];
return !isLiquidityEmpty(liq);
}
function isUnique(uint256[] memory arr) public pure returns (bool) {
if (arr.length == 0) return true;
for (uint256 i = 0; i < arr.length - 1; i++) {
for (uint256 j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) return false;
}
}
return true;
}
function isMaxLen16(uint256[] memory arr) public pure returns (bool) {
return arr.length <= 16;
}
function isZero(address addr) public pure returns (bool) {
return addr == address(0);
}
function setOrDef(address _target, address _default) public pure returns (address) {
return (_target != address(0)) ? _target : _default;
}
function getFeeInfo(
IAssetRegistry assetReg,
Structs.Asset memory asset,
uint256 defaultBp
) public view returns (uint256 feeBp, uint256 fixedFee, uint256 curRate) {
Info memory inf = assetReg.get(asset.addr);
if (inf.feeBp == 0) inf.feeBp = defaultBp;
return (inf.feeBp, inf.feeFixed, inf.curRate);
}
function hasNativeNFT(address nft, address addr) public view returns (bool) {
return nft != address(0) && IERC721Strip(nft).balanceOf(addr) > 0;
}
function checkFungibleSwapParams(StructsLib.SwapSlot memory sp, Structs.Market memory mkt, Structs.Liquidity storage liq) public view {
require(mkt.quote.isNFT() || sp.amount > 0, "OC: AMOUNT_REQ");
require(!mkt.quote.isNFT() || sp.amount == 0, "OC: AMOUNT_NREQ");
require((sp.offerId > 0 && mkt.perms.allowZeroOfferPrice) || mkt.quote.isNFT() || sp.maxPrice > 0, "OC: MAX_PRICE_REQ");
require(!mkt.quote.isNFT() || sp.maxPrice == 0, "OC: MAX_PRICE_NREQ");
require(!mkt.quote.isNFT() || sp.ids.length > 0, "OC: IDS_REQ");
require(mkt.quote.isNFT() || sp.ids.length == 0, "OC: IDS_NREQ");
require(isMaxLen16(sp.ids), "OC: IDS_HSIZE");
require(isUnique(sp.ids), "OC: IDS_NUNIQ");
require(!liq.paused, "OC: LIQ_PAUSED");
require(sp.amount <= liq.amount, "OC: LOW_LIQ");
require(sp.offerId > 0 || sp.amount >= liq.minSwap, "OC: AMOUNT_BELOW_MIN_SWAP");
require(sp.offerId > 0 || liq.maxSwap == 0 || sp.amount <= liq.maxSwap, "OC: AMOUNT_ABOVE_MAX_SWAP");
require(sp.offerId > 0 || sp.maxPrice == 0 || sp.maxPrice >= liq.price, "OC: MAX_PRICE_TOO_LOW");
}
function checkNonFungibleSwapParams(
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt,
Structs.Liquidity storage liq
) public view {
require(sp.amount == 0, "OC: AMOUNT_NREQ");
require(!liq.paused, "OC: LIQ_PAUSED");
require((sp.offerId > 0 && mkt.perms.allowZeroOfferPrice) || mkt.quote.isNFT() || sp.maxPrice > 0, "OC: MAX_PRICE_REQ");
require(!mkt.quote.isNFT() || sp.maxPrice == 0, "OC: MAX_PRICE_NREQ");
require(sp.offerId > 0 || sp.maxPrice == 0 || sp.maxPrice >= liq.price, "OC: MAX_PRICE_TOO_LOW");
require(mkt.quote.isNFT() || sp.ids.length == 0, "OC: IDS_NREQ");
require((sp.offerId > 0 && mkt.perms.allowZeroOfferPrice) || !mkt.quote.isNFT() || sp.ids.length > 0, "OC: IDS_REQ");
}
}
文件 3 的 44:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 44:Core.sol
pragma solidity ^0.8.13;
import "../common/Ownable.sol";
import "../common/Structs.sol";
import "./StructsLib.sol";
import "../market/interfaces/IMarketCore.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "../pools/interfaces/IFeePool.sol";
import "./WithdrawLib.sol";
import "./AuxLib.sol";
import "./FeeLib.sol";
import "./LiquidityLib.sol";
import "./OfferLib.sol";
import "./SwapLib.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../token/interfaces/IERC20.sol";
import "./FungibleLiquidityLib.sol";
import "./NonFungibleLiquidityLib.sol";
contract Core is Ownable, ERC1155Holder {
StructsLib.State public state;
StructsLib.State2 public state2;
event Swap(
address indexed mid,
address indexed provider,
address indexed swapper,
address recipient,
address releaser,
uint256[6] numTypeInfo,
bool byDispute,
uint256[] idsFromProvider,
uint256[] idsFromTaker
);
event SwapOrder(
address indexed mid,
address indexed provider,
address indexed swapper,
address recipient,
uint256[7] numTypeInfo,
uint256[] idsFromProvider,
uint256[] idsFromTaker
);
event SwapOrderPaid(uint256 indexed orderID, address payer, uint256 disputeDelayDur);
event OrderCancelled(uint256 indexed orderID, address indexed canceller, bool indexed byDispute);
event TransferredToFeePool(address indexed token, uint256 amount, address convAsset, uint256 convAmount);
event FinalizedByManagerSig(address manager, address finalizer, uint256 orderId, uint action);
event ProtocolFeeUpdated(
uint256 instantSwapFeeBp,
uint256 synthSwapFeeBp,
uint256 stableSwapFeeBp,
uint256 fixedSynthSwapFee,
uint256 fixedNFTSwapFee,
uint256 instantNFTSwapFeeBp
);
event ProtocolFeeSplitUpdated(uint256 inventor, uint256 shared, uint256 operator);
event TransferInventorBalance(address owner, address token, uint256 amount);
event TransferOperatorBalance(address owner, address token, uint256 amount);
event UpdatedFungibleLiquidity(
address indexed provider,
address indexed marketId,
address target,
bool deduct,
bool paused,
uint256 liq,
uint256 amount,
uint256 price,
uint256[] wantOrIds,
uint256[] wantAndIds,
uint256 minSwap,
uint256 maxSwap,
uint256 timeToPay
);
event UpdatedNonFungibleLiquidity(
address indexed provider,
address indexed marketId,
address target,
bool deduct,
bool paused,
uint256 lid,
uint256[] ids,
uint256 price,
uint256[] wantOrIds,
uint256[] wantAndIds,
uint256 timeToPay
);
event UpdatedPrice(address indexed marketId, address indexed provider, address indexed manager, uint256 lid, uint256 price);
event TogglePause(address indexed marketId, address indexed provider, uint256 lid, bool paused);
event UpdatedLiquidityManager(address indexed marketId, address indexed provider, address indexed manager, address oldManager);
event NFTDiscountUpdated(uint256 bp);
event NewOffer(
address marketId,
address indexed provider,
uint256 lid,
address indexed offerer,
uint256 offerId,
uint256 amount,
uint256 price,
uint256[] ids,
uint256 expireDuration
);
event OfferUpdated(
uint256 indexed offerId,
address indexed offerer,
uint256 amount,
uint256 price,
uint256[] ids,
uint256 execDelayDur
);
event OfferAccepted(uint256 indexed offerId, address indexed acceptor, uint256 executeAt);
event OfferCancelled(uint256 indexed offerId, address indexed canceller);
event OfferExecuted(uint256 indexed offerId, address indexed executor);
event OfferUnaccepted(uint256 indexed offerId, address indexed unacceptor);
event UpdatedLiquiditySwapBadges(address market, address provider, uint256 liq, string[2][] badges);
event UpdatedFeePurse(address addr);
event UpdatedBadge(address addr);
event UpdatedMarketCore(address addr);
event UpdatedFeePool(address addr);
event UpdatedInventor(address addr);
event UpdatedFeePoolConfig(uint256 interval);
event UpdatedAssetRegistry(address addr);
event UpdatedMinTimeToPay(uint256 val);
event UpdatedOrderGraceDur(uint256 val);
event UpdatedMaxOpenOrders(uint256 val);
event UpdatedMaxOpenDisputes(uint256 val);
event UpdatedDisputeManager(address addr);
event UpdatedNFT(address addr);
event UpdatedOperator(address addr);
event UpdatedMinerRegistry(address addr);
event UpdatedAMMInfo(address swapRouter, address ethErc20Addr, uint256 poolFee);
event UpdatedAMMPoolInfo(address input, address output, uint256 poolFee);
modifier marketMustExist(address id) {
require(IMarketCore(state2.marketCore).getMarket(id).createdAt > 0, "OC: UNKNOWN_MARKET");
_;
}
modifier onlyDisputeManager() {
require(msg.sender == state2.disputeManager, "OC: NOT_DISPUTE_MGR");
_;
}
modifier notExpired(uint256 expireAt) {
require(expireAt == 0 || expireAt > block.timestamp, "OC: EXPIRED_TX");
_;
}
modifier onlyInventor() {
require(state.inventor == msg.sender, "OC: NOT_INVENTOR");
_;
}
constructor(
address _marketCore,
address _token,
uint256 _minTimeToPay,
uint256 _orderGraceDur,
uint256 _maxOpenOrders,
uint256 _maxOpenDisputes
) {
state.minTimeToPay = _minTimeToPay;
state.orderGraceDur = _orderGraceDur;
state.ints.maxOpenOrders = _maxOpenOrders;
state.ints.maxOpenDisputes = _maxOpenDisputes;
state.feePoolTxInterval = 12 hours;
state.inventor = msg.sender;
state.feeBPs[0] = 5000;
state.feeBPs[1] = 5000;
state.feeBPs[2] = 0;
state2.token = IERC20(_token);
state2.marketCore = IMarketCore(_marketCore);
state2.ints.nftDiscountBp = 2500;
}
function setAssetRegistry(address addr) external onlyOwner onlyOwner {
state2.assetReg = IAssetRegistry(addr);
emit UpdatedAssetRegistry(addr);
}
function setMinTimeToPay(uint256 val) external onlyOwner {
state.minTimeToPay = val;
emit UpdatedMinTimeToPay(val);
}
function setOrderGraceDur(uint256 val) external onlyOwner {
state.orderGraceDur = val;
emit UpdatedOrderGraceDur(val);
}
function setMaxOpenOrders(uint256 val) external onlyOwner {
state.ints.maxOpenOrders = val;
emit UpdatedMaxOpenOrders(val);
}
function setMaxOpenDisputes(uint256 val) external onlyOwner {
state.ints.maxOpenDisputes = val;
emit UpdatedMaxOpenDisputes(val);
}
function setDisputeManager(address addr) external onlyOwner {
state2.disputeManager = addr;
emit UpdatedDisputeManager(addr);
}
function setOperator(address addr) external onlyOwner {
state2.operatorMgr = IOperator(addr);
emit UpdatedOperator(addr);
}
function setMinerRegistry(address addr) external onlyOwner {
state2.minerReg = IMinerRegistry(addr);
emit UpdatedMinerRegistry(addr);
}
function setNFT(address addr) external onlyOwner {
state2.nft = addr;
emit UpdatedNFT(addr);
}
function setAmmInfo(address swapRouter, address ethErc20Addr, uint256 poolFee) external onlyOwner {
state2.ammEth = ethErc20Addr;
state2.ints.ammEthPoolFee = poolFee;
state.ammSwapRouter = swapRouter;
emit UpdatedAMMInfo(swapRouter, ethErc20Addr, poolFee);
}
function setAmmPoolInfo(address input, address out, uint256 poolFee) external onlyOwner {
state2.ammSwapPool[input] = StructsLib.AmmSwapPoolInfo(out, poolFee);
emit UpdatedAMMPoolInfo(input, out, poolFee);
}
function setFeePurse(address val) external onlyOwner {
state2.feePurse = IFeePurse(val);
emit UpdatedFeePurse(val);
}
function setBadgeMgr(address val) external onlyOwner {
state2.badge = IBadge(val);
emit UpdatedBadge(val);
}
function setMarketCore(address addr) external onlyOwner {
state2.marketCore = IMarketCore(addr);
emit UpdatedMarketCore(addr);
}
function setFeePool(address addr) external onlyOwner {
state2.feePool = IFeePool(addr);
emit UpdatedFeePool(addr);
}
function setInventor(address addr) external onlyInventor {
state.inventor = addr;
emit UpdatedInventor(addr);
}
function configureFeePool(uint256 interval) external onlyOwner {
state.feePoolTxInterval = interval;
emit UpdatedFeePoolConfig(interval);
}
function setDiscountForNFTHolder(uint256 bp) external onlyOwner {
state2.ints.nftDiscountBp = bp;
emit NFTDiscountUpdated(bp);
}
function setProtoFeeSplit(uint256 inventorBP, uint256 sharedBP, uint256 operatorBP) public onlyOwner {
require(inventorBP >= 3000, "OC: INV_BP_TOO_LOW");
require(inventorBP + sharedBP + operatorBP == 10000, "OC: UNBALANCED");
state.feeBPs[0] = inventorBP;
state.feeBPs[1] = sharedBP;
state.feeBPs[2] = operatorBP;
emit ProtocolFeeSplitUpdated(inventorBP, sharedBP, operatorBP);
}
function getFeeBPs() public view returns (uint256[3] memory) {
return state.feeBPs;
}
function isVerified(address addr) public view returns (bool) {
return AuxLib.isVerified(state2, addr);
}
function setProtoFee(
uint256 _instantSwapFeeBp,
uint256 _synthSwapFeeBp,
uint256 _stableSwapFeeBp,
uint256 _fixedSynthSwapFee,
uint256 _fixedNFTSwapFee,
uint256 _instantNFTSwapFeeBp
) public {
state.ints.instantSwapFeeBp = _instantSwapFeeBp;
state.ints.synthSwapFeeBp = _synthSwapFeeBp;
state.ints.stableSwapFeeBp = _stableSwapFeeBp;
state.ints.instantNFTSwapFeeBp = _instantNFTSwapFeeBp;
state.ints.fixedSynthSwapFee = _fixedSynthSwapFee;
state.ints.fixedNFTSwapFee = _fixedNFTSwapFee;
emit ProtocolFeeUpdated(
_instantSwapFeeBp,
_synthSwapFeeBp,
_stableSwapFeeBp,
_fixedSynthSwapFee,
_fixedNFTSwapFee,
_instantNFTSwapFeeBp
);
}
function feeBalanceOf(address _owner, address _asset) external view returns (uint256) {
return state.feeBalance[_owner][_asset];
}
function inventorBalanceOf(address asset) external view returns (uint256) {
return state.inventorBalance[asset];
}
function shareablesBalanceOf(address asset) external view returns (uint256) {
return state.shareablesBalance[asset];
}
function operatorBalanceOf(address operator, address asset) external view returns (uint256) {
return state.operatorsBalance[operator][asset];
}
function withdrawFeeBalance(address asset) external {
uint256 bal = state.feeBalance[msg.sender][asset];
state.feeBalance[msg.sender][asset] = 0;
IERC20(asset).transfer(msg.sender, bal);
}
function swapQuoteForBase(
address marketId,
address provider,
address recipient,
uint256 lid,
uint256 amount,
uint256 maxPrice,
uint256[] memory ids,
uint256 txDeadline,
uint256 operator
) external payable notExpired(txDeadline) marketMustExist(marketId) {
StructsLib.SwapSlotAddresses memory addrs = StructsLib.SwapSlotAddresses(marketId, provider, recipient);
SwapLib.swapQuoteForBase(state, state2, StructsLib.SwapSlot(lid, amount, maxPrice, ids, 0, operator, addrs));
}
function computeSwapFee(
address mid,
address provider,
uint256 lid,
address taker,
uint256 orderAmt,
uint256 orderPrice
) public view returns (uint256, uint256, uint256, uint256) {
Structs.Market memory mkt = state2.marketCore.getMarket(mid);
Structs.Liquidity memory liq = state.liquidity[mid][provider][lid];
FeeInfo memory info = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
state2.assetReg,
state2.feePurse,
state.ints.synthSwapFeeBp,
state.ints.instantNFTSwapFeeBp,
state.ints.instantSwapFeeBp,
state.ints.stableSwapFeeBp,
state2.ints.nftDiscountBp,
lid,
orderAmt,
orderPrice,
state2.nft,
provider,
taker
)
);
return (info.protoFee, info.mktCreatorFee, info.feeBp, info.mktFeeBp);
}
function withdrawInventorBalance(address asset) external onlyInventor {
WithdrawLib.withdrawInventorBalance(state, state2, asset);
}
function releaseOrder(uint256 id) external {
require(id <= state.orders.length - 1, "OC: UNKNOWN_ORDER");
SwapLib.releaseOrder(state, state2, owner(), id, false);
}
function releaseOrderByManagerSig(uint256 id, uint256 expireAt, bytes calldata signature) external {
require(id <= state.orders.length - 1, "OC: UNKNOWN_ORDER");
SwapLib.releaseOrderByManagerSig(state, state2, owner(), id, expireAt, signature);
}
function releaseOrderByDispute(uint256 id) external onlyDisputeManager {
SwapLib.releaseOrder(state, state2, owner(), id, true);
}
function cancelOrder(uint256 id) external {
require(hasOrder(id), "OC: UNKNOWN_ORDER");
SwapLib.cancelOrder(state, state2, owner(), id, false);
}
function cancelOrderByManagerSig(uint256 id, uint256 expireAt, bytes calldata signature) external {
require(id <= state.orders.length - 1, "OC: UNKNOWN_ORDER");
SwapLib.cancelOrderByManagerSig(state, state2, owner(), id, expireAt, signature);
}
function cancelOrderByDispute(uint256 id) external onlyDisputeManager {
SwapLib.cancelOrder(state, state2, owner(), id, true);
}
function markOrderAsPaid(uint256 id) external {
SwapLib.markOrderAsPaid(state, state2.marketCore, id, false);
}
function markOrderAsPaidByManagerSig(uint256 id, uint256 expireAt, bytes calldata signature) external {
require(id <= state.orders.length - 1, "OC: UNKNOWN_ORDER");
SwapLib.markOrderAsPaidByManagerSig(state, state2, id, expireAt, signature);
}
function hasOrder(uint256 id) public view returns (bool) {
return AuxLib.hasOrder(state, id);
}
function canCreateDispute(uint256 id, address addr) external view returns (bool) {
return AuxLib.canCreateDispute(state, state2, id, addr);
}
function markAsDisputed(uint256 id) external onlyDisputeManager {
SwapLib.markAsDisputed(state, state2.marketCore, id);
}
function getOrder(uint256 id) external view returns (Structs.Order memory) {
require(hasOrder(id), "OC: UNKNOWN_ORDER");
return state.orders[id];
}
function getOffer(uint256 id) external view returns (Structs.Offer memory) {
require(id < state2.offers.length, "OC: UNKNOWN_OFFER");
return state2.offers[id];
}
function getMarket(address id) external view marketMustExist(id) returns (Structs.Market memory) {
return state2.marketCore.getMarket(id);
}
function transferToFeePool(address _token) external {
WithdrawLib.transferToFeePool(state, state2, _token);
}
function withdrawOperatorBalance(address _token) external {
WithdrawLib.withdrawOperatorBalance(state, state2, _token);
}
function getLiquidity(address _mid, address _owner, uint256 _lid) external view returns (Structs.Liquidity memory) {
return state.liquidity[_mid][_owner][_lid];
}
function hasLiquidity(address _mid, address _owner, uint256 _lid) external view returns (bool) {
return AuxLib.isLiquidityExist(state, _mid, _owner, _lid);
}
function setLiquidityManager(address marketId, address manager) external {
LiquidityLib.setLiquidityManager(state, marketId, manager);
}
function getLiquidityManager(address marketId, address provider) external view returns (address) {
return state.liqManagers[provider][marketId];
}
function updateFungibleLiquidity(
address marketId,
uint256 lid,
bool deduct,
address target,
uint256[2] memory amountAndPrice,
uint256[] memory wantOrIds,
uint256[] memory wantAndIds,
uint256[5] memory limits
) external payable notExpired(limits[3]) marketMustExist(marketId) {
StructsLib.UpdateLiquiditySlot memory slot = StructsLib.UpdateLiquiditySlot(
marketId,
lid,
deduct,
limits[4] > 0,
amountAndPrice[0],
new uint256[](0),
wantOrIds,
wantAndIds,
amountAndPrice[1],
limits[0],
limits[1],
limits[2],
target
);
FungibleLiquidityLib.updateFungibleLiquidity(state, state2, slot);
}
function updateNonFungibleLiquidity(
address marketId,
uint256 lid,
bool deduct,
address target,
uint256[] memory ids,
uint256 price,
uint256[] memory wantOrIds,
uint256[] memory wantAndIds,
uint256[3] memory limits
) external notExpired(limits[1]) marketMustExist(marketId) {
StructsLib.UpdateLiquiditySlot memory slot = StructsLib.UpdateLiquiditySlot(
marketId,
lid,
deduct,
limits[2] > 0,
0,
ids,
wantOrIds,
wantAndIds,
price,
0,
0,
limits[0],
target
);
NonFungibleLiquidityLib.updateNonFungibleLiquidity(state, state2, slot);
}
function setSwapBadgeForLiquidity(address marketId, uint256 lid, string[2][] memory badgeIds) external {
LiquidityLib.setSwapBadgeForLiquidity(state, state2, marketId, lid, badgeIds);
}
function getReqSwapBadges(address marketId, uint256 lid, address addr) external view returns (string[2][] memory) {
return state2.reqSwapBadges[marketId][addr][lid];
}
function updateOpenDisputesCount(address marketId, address provider, uint256 lid, bool incr) public onlyDisputeManager {
LiquidityLib.updateOpenDisputesCount(state, marketId, provider, lid, incr);
}
function updateLiquidityPrice(
address _marketId,
address _owner,
uint256 _lid,
uint256 _price,
uint256 _expireAt
) external notExpired(_expireAt) marketMustExist(_marketId) {
LiquidityLib.updateLiquidityPrice(state, state2, _marketId, _owner, _lid, _price);
}
function createOffer(
address marketId,
address provider,
address recipient,
uint256 lid,
uint256 amount,
uint256 price,
uint256[] memory ids,
uint256 deadline,
uint256 operator
) public {
OfferLib.CreateOfferAddressParams memory offerAddrs = OfferLib.CreateOfferAddressParams(marketId, provider, recipient);
OfferLib.CreateOfferIntParams memory offerInts = OfferLib.CreateOfferIntParams(lid, amount, price, deadline, operator);
OfferLib.createOffer(state, state2, offerAddrs, offerInts, ids);
}
function updateOffer(uint256 offerId, uint256 amount, uint256 price, uint256[] memory ids, uint256 deadline) public {
OfferLib.updateOffer(state, state2, offerId, amount, price, ids, deadline);
}
function acceptOffer(uint256 offerId, uint256 delay) public {
OfferLib.acceptOffer(state2, offerId, delay);
}
function unacceptOffer(uint256 offerId) public {
OfferLib.unacceptOffer(state2, offerId);
}
function cancelOffer(uint256 offerId) public {
OfferLib.cancelOffer(state2, offerId);
}
function executeOffer(uint256 offerId, uint256 txDeadline) public notExpired(txDeadline) {
OfferLib.executeOffer(state, state2, offerId);
}
function togglePause(address marketId, uint256 lid, uint256 expireAt) public notExpired(expireAt) {
LiquidityLib.togglePause(state, marketId, lid);
}
}
文件 5 的 44:ECDSA.sol
pragma solidity ^0.8.0;
import "../Strings.sol";
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
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);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
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) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 6 的 44:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 7 的 44:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 8 的 44:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 9 的 44:FeeLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../common/SigLib.sol";
import "./AuxLib.sol";
import "./StructsLib.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../market/MarketAuxLib.sol";
import "../feepurse/interfaces/IFeePurse.sol";
struct FeeInfo {
uint256 cost;
uint256 feeBp;
uint256 amtToCharge;
uint256 mktCreatorFee;
uint256 protoFee;
uint256 totalFees;
uint256 remaining;
uint256 protoFeeRate;
uint256 mktCreatorFeeRate;
uint256 mktFeeBp;
}
struct ComputeFeeParams {
Structs.Market mkt;
Structs.Liquidity liq;
IAssetRegistry assetReg;
IFeePurse feePurse;
uint256 synthSwapFeeBp;
uint256 instantNFTSwapFeeBp;
uint256 instantSwapFeeBp;
uint256 stableSwapFeeBp;
uint256 nftDiscountBp;
uint256 lid;
uint256 amount;
uint256 price;
address nft;
address provider;
address taker;
}
library FeeLib {
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
function computeFee(ComputeFeeParams memory p) public view returns (FeeInfo memory) {
FeeInfo memory feeInfo;
if (
(p.mkt.base.isERC20() && p.mkt.quote.isERC20()) ||
(p.mkt.base.isERC20() && p.mkt.quote.isNative()) ||
(p.mkt.base.isNative() && p.mkt.quote.isERC20()) ||
(p.mkt.base.isNative() && p.mkt.quote.isNative())
) {
(feeInfo.feeBp, , ) = AuxLib.getFeeInfo(p.assetReg, p.mkt.base, p.instantSwapFeeBp);
feeInfo.feeBp = AuxLib.isStable(p.assetReg, p.mkt) ? p.stableSwapFeeBp : feeInfo.feeBp;
feeInfo.mktFeeBp = p.mkt.commission;
uint256 denom = 10000;
if (p.nft != address(0) && AuxLib.hasNativeNFT(p.nft, p.taker)) {
feeInfo.feeBp = feeInfo.feeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.feeBp * 10 ** 2) / denom);
feeInfo.mktFeeBp = feeInfo.mktFeeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.mktFeeBp * 10 ** 2) / denom);
denom = 1000000;
}
feeInfo.mktCreatorFee = (p.amount * feeInfo.mktFeeBp) / denom;
feeInfo.protoFee = (p.amount * feeInfo.feeBp) / denom;
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
return feeInfo;
}
if (p.mkt.isFungible() && p.mkt.hasERC20OrNative()) {
Structs.Asset memory asset = p.mkt.base.isOnchain() ? p.mkt.base : p.mkt.quote;
uint decimals = (p.mkt.quote.isSynth() || p.mkt.quote.isNative()) ? 10 ** 18 : 10 ** IERC20(p.mkt.base.addr).decimals();
feeInfo.cost = (p.amount * p.price) / decimals;
feeInfo.mktFeeBp = p.mkt.commission;
(feeInfo.feeBp, , ) = AuxLib.getFeeInfo(p.assetReg, asset, p.synthSwapFeeBp);
uint256 denom = 10000;
if (AuxLib.hasNativeNFT(p.nft, (p.mkt.quote.isSynth()) ? p.taker : p.provider)) {
feeInfo.mktFeeBp = feeInfo.mktFeeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.mktFeeBp * 10 ** 2) / denom);
feeInfo.feeBp = feeInfo.feeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.feeBp * 10 ** 2) / denom);
denom = 1000000;
}
feeInfo.amtToCharge = (p.mkt.base.isSynth()) ? feeInfo.cost : p.amount;
feeInfo.mktCreatorFee = (feeInfo.amtToCharge * feeInfo.mktFeeBp) / denom;
feeInfo.protoFee = (feeInfo.amtToCharge * feeInfo.feeBp) / denom;
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
return feeInfo;
}
if ((p.mkt.base.isERC20() || p.mkt.base.isNative()) && p.mkt.quote.isNFT()) {
(feeInfo.feeBp, , ) = AuxLib.getFeeInfo(p.assetReg, p.mkt.base, p.instantNFTSwapFeeBp);
feeInfo.mktFeeBp = p.mkt.commission;
uint256 denom = 10000;
if (p.nft != address(0) && AuxLib.hasNativeNFT(p.nft, p.taker)) {
feeInfo.feeBp = feeInfo.feeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.feeBp * 10 ** 2) / denom);
feeInfo.mktFeeBp = feeInfo.mktFeeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.mktFeeBp * 10 ** 2) / denom);
denom = 1000000;
}
feeInfo.mktCreatorFee = (p.liq.amount * feeInfo.mktFeeBp) / denom;
feeInfo.protoFee = (p.liq.amount * feeInfo.feeBp) / denom;
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
}
if (p.mkt.base.isSynth() && (p.mkt.quote.isSynth() || p.mkt.quote.isNFT())) {
feeInfo.remaining = p.liq.amount;
feeInfo.protoFeeRate = p.liq.protoFeeRate;
feeInfo.mktCreatorFeeRate = p.liq.mktCreatorFeeRate;
feeInfo.protoFee = (feeInfo.protoFeeRate * p.amount) / 10 ** 18;
feeInfo.mktCreatorFee = (feeInfo.mktCreatorFeeRate * p.amount) / 10 ** 18;
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
return feeInfo;
}
if (p.mkt.base.isNFT() && (p.mkt.quote.isERC20() || p.mkt.quote.isNative())) {
(feeInfo.feeBp, , ) = AuxLib.getFeeInfo(p.assetReg, p.mkt.base, p.instantNFTSwapFeeBp);
feeInfo.mktFeeBp = p.mkt.commission;
uint256 denom = 10000;
if (p.nft != address(0) && AuxLib.hasNativeNFT(p.nft, p.provider)) {
feeInfo.feeBp = feeInfo.feeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.feeBp * 10 ** 2) / denom);
feeInfo.mktFeeBp = feeInfo.mktFeeBp * 10 ** 2 - ((p.nftDiscountBp * feeInfo.mktFeeBp * 10 ** 2) / denom);
denom = 1000000;
}
feeInfo.mktCreatorFee = (p.price * feeInfo.mktFeeBp) / denom;
feeInfo.protoFee = (p.price * feeInfo.feeBp) / denom;
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
return feeInfo;
}
if (p.mkt.base.isNFT() && p.mkt.quote.isSynth()) {
feeInfo.protoFee = p.feePurse.getLocked(p.liq.protoFeePurseId);
feeInfo.mktCreatorFee = p.feePurse.getLocked(p.liq.mktCreatorFeePurseId);
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
return feeInfo;
}
if (p.mkt.base.isNFT() && p.mkt.quote.isNFT()) {
feeInfo.protoFee = p.feePurse.getLocked(p.liq.protoFeePurseId);
feeInfo.mktCreatorFee = p.feePurse.getLocked(p.liq.mktCreatorFeePurseId);
feeInfo.totalFees = feeInfo.mktCreatorFee + feeInfo.protoFee;
return feeInfo;
}
return feeInfo;
}
}
文件 10 的 44:FungibleLiquidityLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "../token/interfaces/IERC721.sol";
import "../token/interfaces/IERC1155.sol";
import "../common/StrippedInterfaces.sol";
import "../common/MathLib.sol";
import "./AuxLib.sol";
import "../market/MarketAuxLib.sol";
import "./StructsLib.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../feepurse/interfaces/IFeePurse.sol";
import "./LiqAuxLib.sol";
library FungibleLiquidityLib {
using SafeERC20 for IERC20;
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
using AuxLib for uint256[];
using AuxLib for Structs.Market;
using AuxLib for Structs.Liquidity;
using AuxLib for address;
event UpdatedFungibleLiquidity(
address indexed provider,
address indexed marketId,
address target,
bool deduct,
bool paused,
uint256 liq,
uint256 amount,
uint256 price,
uint256[] wantOrIds,
uint256[] wantAndIds,
uint256 minSwap,
uint256 maxSwap,
uint256 timeToPay
);
function updateFungibleLiquidity(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.UpdateLiquiditySlot memory slot
) external {
require(slot.deduct || s2.marketCore.isPutPermitted(slot.marketId, msg.sender));
Structs.Market memory mkt = s2.marketCore.getMarket(slot.marketId);
require(mkt.base.isFungible(), "OC: UNEXP_BASE");
require(!mkt.isInstantMarket() || slot.timeToPay == 0, "OC: TTP_NREQ");
require(slot.timeToPay == 0 || slot.timeToPay >= s1.minTimeToPay, "OC: LOW_TTP");
require(mkt.quote.isNFT() || slot.price > 0, "OC: PRICE_REQ");
require(!mkt.quote.isNFT() || slot.price == 0, "OC: PRICE_NREQ");
require(mkt.quote.isNFT() || (slot.wantOrIds.length == 0 && slot.wantAndIds.length == 0), "OC: WANT_IDS_NREQ");
require(slot.wantOrIds.isUnique() && slot.wantAndIds.isUnique(), "OC: WANT_IDS_NUNIQ");
require(slot.wantOrIds.isMaxLen16() && slot.wantAndIds.isMaxLen16(), "OC: WANT_IDS_HSIZE");
require(!mkt.quote.isNFT() || (slot.minSwap == 0 && slot.maxSwap == 0), "OC: MIN_MAX_SWAP_NREQ");
require(slot.minSwap == 0 || slot.maxSwap == 0 || slot.minSwap < slot.maxSwap, "OC: MIN_MAX_SWAP_INV");
LiqAuxLib.checkMarketPutBadges(s2, slot.marketId);
Structs.Liquidity storage liq;
if (AuxLib.isLiquidityExist(s1, slot.marketId, msg.sender, slot.lid)) {
liq = s1.liquidity[slot.marketId][msg.sender][slot.lid];
} else {
uint256[] memory zero = new uint256[](0);
s1.liquidity[slot.marketId][msg.sender].push(
Structs.Liquidity(zero, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, zero, zero, false, slot.target)
);
slot.lid = s1.liquidity[slot.marketId][msg.sender].length - 1;
liq = s1.liquidity[slot.marketId][msg.sender][slot.lid];
}
require(!liq.isLiquidityEmpty() || slot.amount > 0, "OC: AMOUNT_REQ");
if (!slot.deduct && slot.amount > 0) {
liq.amount += slot.amount;
mkt.numLiquidity += slot.amount;
if (mkt.base.isERC20()) {
IERC20(mkt.base.addr).safeTransferFrom(msg.sender, address(this), slot.amount);
}
if (mkt.base.isNative()) {
require(msg.value >= slot.amount, "OC: LOW_DEPOSIT");
}
if (!mkt.hasERC20OrNative()) {
LiqAuxLib.lockFeeForProtocol(s1, s2, mkt, liq, slot.amount);
LiqAuxLib.lockFeeForMarketCreator(s2, mkt, liq, slot.amount);
}
}
if (slot.deduct && slot.amount > 0) {
require(liq.amount >= slot.amount, "OC: LOW_LIQ");
liq.amount -= slot.amount;
mkt.numLiquidity -= slot.amount;
if (mkt.base.isERC20()) {
IERC20(mkt.base.addr).safeTransfer(msg.sender, slot.amount);
}
if (mkt.base.isNative()) {
payable(msg.sender).transfer(slot.amount);
}
if (!mkt.hasERC20OrNative()) {
LiqAuxLib.unlockFeeForProtocol(s2, mkt, liq);
LiqAuxLib.unlockFeeForMarketCreator(s2, mkt, liq);
}
}
liq.timeToPay = slot.timeToPay;
liq.price = slot.price;
liq.minSwap = slot.minSwap;
liq.maxSwap = slot.maxSwap;
liq.wantAndIds = slot.wantAndIds;
liq.wantOrIds = slot.wantOrIds;
liq.target = slot.target;
liq.paused = slot.pause;
s2.marketCore.setCounters(slot.marketId, false, false, true, mkt.numLiquidity);
emit UpdatedFungibleLiquidity(
msg.sender,
slot.marketId,
slot.target,
slot.deduct,
slot.pause,
slot.lid,
slot.amount,
slot.price,
slot.wantOrIds,
slot.wantAndIds,
slot.minSwap,
slot.maxSwap,
slot.timeToPay
);
}
}
文件 11 的 44:IAssetRegistry.sol
pragma solidity ^0.8.13;
struct Info {
uint256 curRate;
uint256 feeBp;
uint256 feeFixed;
bool verified;
bool stable;
bool sharable;
}
interface IAssetRegistry {
function set(address addr, uint256 curRate, uint256 feeBp, uint256 feeFixed, bool verified, bool stable, bool sharable) external;
function setRate(address addr, uint256 rate) external;
function setFee(uint256 feeBp, uint256 feeFixed) external;
function get(address addr) external view returns (Info memory);
function setVerified(address addr, bool verified) external;
function setSharable(address addr, bool sharable) external;
function getRate(address addr) external view returns (uint256);
function setStable(address addr, bool stable) external;
function toCur(address addr, uint256 value) external returns (uint256);
}
文件 12 的 44:IBadge.sol
pragma solidity ^0.8.13;
import "../../common/Structs.sol";
interface IBadge {
function hasBadge(address addr, string memory badge, string memory path) external view returns (bool);
}
文件 13 的 44:IERC1155.sol
pragma solidity ^0.8.13;
interface IERC1155 {
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
}
文件 14 的 44:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 15 的 44:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 16 的 44:IERC20.sol
pragma solidity ^0.8.13;
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function decimals() external view returns (uint8);
function allowance(address owner, address spender) external view returns (uint256);
function burn(uint256 amount) external;
function mint(address to, uint256 amount) external;
function approve(address spender, uint256 amount) external returns (bool);
}
文件 17 的 44:IERC721.sol
pragma solidity ^0.8.13;
interface IERC721 {
function transferFrom(address from, address to, uint256 tokenId) external;
}
文件 18 的 44:IFeePool.sol
pragma solidity ^0.8.13;
interface IFeePool {
function notifyWithdraw(address account, uint256 _amount) external;
function notifyStake(address account, uint256 _amount) external;
function notifyFeeDeposit(address token, uint256 amount) external;
function withdrawReward(address feeToken, uint256 _amount) external;
function earned(address account, address feeToken) external view returns (uint256);
}
文件 19 的 44:IFeePurse.sol
pragma solidity ^0.8.13;
interface IFeePurse {
function balanceOf(address owner) external view returns (uint256);
function lock(address owner, uint256 amt) external returns (uint256);
function unlock(address owner, uint256 id) external;
function transferFrom(address from, address to, uint256 amt) external;
function getLocked(uint256 id) external view returns (uint256);
function withdraw(uint256 amt, address to) external;
function withdrawFrom(uint256 amt, address from, address to) external;
function getFeeToken() external view returns (address);
}
文件 20 的 44:IMarketCore.sol
pragma solidity ^0.8.13;
import "../../common/Ownable.sol";
import "../../common/Structs.sol";
interface IMarketCore {
function setInventor(address val) external;
function createMarket(
address base,
address quote,
bool isBaseLocal,
bool isQuoteLocal,
bool permPut,
bool permSwap,
bool permMediate,
uint256 commission,
uint256 mediatorBond,
uint256 numMediators
) external;
function getNativeAssetAddr() external view returns (address);
function getMarket(address id) external view returns (Structs.Market memory);
function permitPut(address id, address addr) external;
function revokePut(address id, address addr) external;
function permitSwap(address id, address addr) external;
function revokeSwap(address id, address addr) external;
function hasMarket(address id) external view returns (bool);
function setCounters(address id, bool numOrders, bool numDisputes, bool numLiquidity, uint256 value) external;
function setCommission(address id, uint256 val) external;
function setLiquidityManager(address marketId, address manager) external;
function getLiquidityManager(address marketId, address provider, uint256 lid) external view returns (address);
function isPutPermitted(address id, address sender) external view returns (bool);
function isSwapPermitted(address id, address sender) external view returns (bool);
function getReqBadges(address id) external view returns (string[2][] memory, string[2][] memory);
}
文件 21 的 44:IMinerRegistry.sol
pragma solidity ^0.8.13;
enum MinerOperation {
Draft,
Undraft,
Execute,
Cancel
}
interface IMinerRegistry {
function isMiner(address _address) external view returns (bool);
function addReward(MinerOperation op, address miner) external;
}
文件 22 的 44:IOperator.sol
pragma solidity ^0.8.13;
interface IOperator {
function isOperator(uint256 id) external returns (bool);
function getOperator(uint256 id) external returns (address);
}
文件 23 的 44:ISwapRouter.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';
interface ISwapRouter is IUniswapV3SwapCallback {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
}
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
struct ExactOutputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
}
function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}
文件 24 的 44:IUniswapV3SwapCallback.sol
pragma solidity >=0.5.0;
interface IUniswapV3SwapCallback {
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
) external;
}
文件 25 的 44:LiqAuxLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "../token/interfaces/IERC721.sol";
import "../token/interfaces/IERC1155.sol";
import "../common/StrippedInterfaces.sol";
import "../common/MathLib.sol";
import "./AuxLib.sol";
import "../market/MarketAuxLib.sol";
import "./StructsLib.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../feepurse/interfaces/IFeePurse.sol";
library LiqAuxLib {
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
function lockFeeForProtocol(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
Structs.Market memory mkt,
Structs.Liquidity storage liq,
uint256 amount
) internal {
(, uint256 fixedFee, ) = AuxLib.getFeeInfo(s2.assetReg, mkt.base, 0);
uint256 fixedFeeInternal = mkt.base.isSynth() ? s1.ints.fixedSynthSwapFee : s1.ints.fixedNFTSwapFee;
uint256 fee = amount * ((fixedFee > 0) ? fixedFee : fixedFeeInternal);
fee = mkt.base.isSynth() ? fee / 10 ** 18 : fee;
if (fee > 0 && AuxLib.hasNativeNFT(s2.nft, msg.sender) && s2.ints.nftDiscountBp > 0) {
fee = fee - (fee * s2.ints.nftDiscountBp) / 10000;
}
if (fee > 0) {
uint256 prevLockedFee = s2.feePurse.getLocked(liq.protoFeePurseId);
if (prevLockedFee > 0) s2.feePurse.unlock(msg.sender, liq.protoFeePurseId);
liq.protoFeePurseId = s2.feePurse.lock(msg.sender, prevLockedFee + fee);
}
uint256 curLiqAmt = mkt.base.isSynth() ? liq.amount : liq.ids.length;
uint256 curLocked = s2.feePurse.getLocked(liq.protoFeePurseId);
liq.protoFeeRate = (mkt.base.isSynth() ? (curLocked * 10 ** 18) : curLocked) / curLiqAmt;
}
function unlockFeeForProtocol(StructsLib.State2 storage s2, Structs.Market memory mkt, Structs.Liquidity storage liq) internal {
uint256 remaining = mkt.base.isSynth() ? liq.amount : liq.ids.length;
if (remaining == 0) {
s2.feePurse.unlock(msg.sender, liq.protoFeePurseId);
liq.protoFeeRate = 0;
liq.protoFeePurseId = 0;
return;
}
s2.feePurse.unlock(msg.sender, liq.protoFeePurseId);
uint256 newAmtToLck = liq.protoFeeRate * remaining;
newAmtToLck = mkt.base.isSynth() ? newAmtToLck / 10 ** 18 : newAmtToLck;
liq.protoFeePurseId = (newAmtToLck > 0) ? s2.feePurse.lock(msg.sender, newAmtToLck) : 0;
uint256 curLocked = s2.feePurse.getLocked(liq.protoFeePurseId);
liq.protoFeeRate = (mkt.base.isSynth() ? (curLocked * 10 ** 18) : curLocked) / remaining;
}
function lockFeeForMarketCreator(
StructsLib.State2 storage s2,
Structs.Market memory mkt,
Structs.Liquidity storage liq,
uint256 amount
) internal {
uint256 fee = amount * mkt.commission;
fee = mkt.base.isSynth() ? fee / 10 ** 18 : fee;
if (fee > 0 && AuxLib.hasNativeNFT(s2.nft, msg.sender) && s2.ints.nftDiscountBp > 0) {
fee = fee - (fee * s2.ints.nftDiscountBp) / 10000;
}
if (fee > 0) {
uint256 prevLockedFee = s2.feePurse.getLocked(liq.mktCreatorFeePurseId);
if (prevLockedFee > 0) s2.feePurse.unlock(msg.sender, liq.mktCreatorFeePurseId);
liq.mktCreatorFeePurseId = s2.feePurse.lock(msg.sender, prevLockedFee + fee);
}
uint256 curLiqAmt = mkt.base.isSynth() ? liq.amount : liq.ids.length;
uint256 curLocked = s2.feePurse.getLocked(liq.mktCreatorFeePurseId);
liq.mktCreatorFeeRate = (mkt.base.isSynth() ? (curLocked * 10 ** 18) : curLocked) / curLiqAmt;
}
function unlockFeeForMarketCreator(StructsLib.State2 storage s2, Structs.Market memory mkt, Structs.Liquidity storage liq) internal {
uint256 remaining = mkt.base.isSynth() ? liq.amount : liq.ids.length;
if (remaining == 0) {
s2.feePurse.unlock(msg.sender, liq.mktCreatorFeePurseId);
liq.mktCreatorFeeRate = 0;
liq.mktCreatorFeePurseId = 0;
return;
}
s2.feePurse.unlock(msg.sender, liq.mktCreatorFeePurseId);
uint256 newAmtToLck = liq.mktCreatorFeeRate * remaining;
newAmtToLck = mkt.base.isSynth() ? newAmtToLck / 10 ** 18 : newAmtToLck;
liq.mktCreatorFeePurseId = (newAmtToLck > 0) ? s2.feePurse.lock(msg.sender, newAmtToLck) : 0;
uint256 curLocked = s2.feePurse.getLocked(liq.mktCreatorFeePurseId);
liq.mktCreatorFeeRate = (mkt.base.isSynth() ? (curLocked * 10 ** 18) : curLocked) / remaining;
}
function checkMarketPutBadges(StructsLib.State2 storage s2, address marketId) internal view {
(string[2][] memory reqPutBadges, ) = s2.marketCore.getReqBadges(marketId);
if (reqPutBadges.length > 0) {
uint256 len = reqPutBadges.length;
for (uint256 i = 0; i < len; i++) {
require(s2.badge.hasBadge(msg.sender, reqPutBadges[i][0], reqPutBadges[i][1]), "OC: MKT_BADGE_REQ");
}
}
}
}
文件 26 的 44:LiquidityLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "../token/interfaces/IERC721.sol";
import "../token/interfaces/IERC1155.sol";
import "../common/StrippedInterfaces.sol";
import "../common/MathLib.sol";
import "./AuxLib.sol";
import "../market/MarketAuxLib.sol";
import "./StructsLib.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../feepurse/interfaces/IFeePurse.sol";
library LiquidityLib {
using SafeERC20 for IERC20;
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
using AuxLib for uint256[];
using AuxLib for Structs.Market;
using AuxLib for Structs.Liquidity;
using AuxLib for address;
event UpdatedPrice(address indexed marketId, address indexed provider, address indexed manager, uint256 lid, uint256 price);
event TogglePause(address indexed marketId, address indexed provider, uint256 lid, bool paused);
event UpdatedLiquidityManager(address indexed marketId, address indexed provider, address indexed manager, address oldManager);
event UpdatedLiquiditySwapBadges(address marketId, address provider, uint256 lid, string[2][] badges);
function findMatchInWantIds(
uint256[] memory ids,
mapping(uint256 => bool) storage intIdx,
uint256[] memory wantOrIds,
uint256[] memory wantAndIds
) public returns (uint256[] memory) {
if (wantOrIds.length == 0 && wantAndIds.length == 0) return ids;
uint256[] memory matchIds = new uint256[](ids.length);
mapping(uint256 => bool) storage matchIdx = intIdx;
uint256 idx;
uint256 andFound;
for (uint256 i = 0; i < wantAndIds.length; i++) {
for (uint256 j = 0; j < ids.length; j++) {
if (wantAndIds[i] == ids[j] && !matchIdx[ids[j]]) {
matchIds[idx] = ids[j];
matchIdx[ids[j]] = true;
idx++;
andFound++;
}
}
}
if (andFound != wantAndIds.length) return new uint256[](0);
bool orFound = wantOrIds.length == 0;
for (uint256 i = 0; i < wantOrIds.length; i++) {
for (uint256 j = 0; j < ids.length; j++) {
if (wantOrIds[i] == ids[j]) {
if (!matchIdx[ids[j]]) matchIds[idx] = ids[j];
orFound = true;
break;
}
}
if (orFound) break;
}
return (orFound) ? matchIds : new uint256[](0);
}
function updateOpenDisputesCount(StructsLib.State storage state, address marketId, address provider, uint256 lid, bool incr) external {
Structs.Liquidity storage liq = state.liquidity[marketId][provider][lid];
if (incr) liq.openDisputes++;
else liq.openDisputes--;
}
function setLiquidityManager(StructsLib.State storage state, address marketId, address manager) external {
address old = state.liqManagers[msg.sender][marketId];
state.liqManagers[msg.sender][marketId] = manager;
emit UpdatedLiquidityManager(marketId, msg.sender, manager, old);
}
function updateLiquidityPrice(
StructsLib.State storage state,
StructsLib.State2 storage state2,
address marketId,
address owner,
uint256 lid,
uint256 price
) external {
require(state.liqManagers[owner][marketId] == msg.sender, "OC: NOT_MANAGER");
Structs.Liquidity storage liq = state.liquidity[marketId][owner][lid];
require(price > 0, "OC: PRICE_REQ");
Structs.Market memory market = state2.marketCore.getMarket(marketId);
require(MarketAuxLib.isFungible(market.quote), "OC: PRICE_NREQ");
liq.price = price;
emit UpdatedPrice(marketId, owner, msg.sender, lid, price);
}
function togglePause(StructsLib.State storage state, address mid, uint256 lid) external {
require(AuxLib.hasNonZeroLiquidity(state, mid, msg.sender, lid), "OC: ZERO_LIQ");
state.liquidity[mid][msg.sender][lid].paused = !state.liquidity[mid][msg.sender][lid].paused;
emit TogglePause(mid, msg.sender, lid, state.liquidity[mid][msg.sender][lid].paused);
}
function setSwapBadgeForLiquidity(
StructsLib.State storage state,
StructsLib.State2 storage state2,
address mid,
uint256 lid,
string[2][] memory badges
) external {
require(AuxLib.hasNonZeroLiquidity(state, mid, msg.sender, lid), "OC: ZERO_LIQ");
require(badges.length <= 8, "OC: TOO_MANY_BADGES");
state2.reqSwapBadges[mid][msg.sender][lid] = badges;
emit UpdatedLiquiditySwapBadges(mid, msg.sender, lid, badges);
}
}
文件 27 的 44:MarketAuxLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
library MarketAuxLib {
function isNative(Structs.Asset memory asset) public pure returns (bool) {
return (asset.assetType == Structs.AssetType.NATIVE);
}
function isSynth(Structs.Asset memory asset) public pure returns (bool) {
return (asset.assetType == Structs.AssetType.SYNTH);
}
function isERC20(Structs.Asset memory asset) public pure returns (bool) {
return (asset.assetType == Structs.AssetType.ERC20);
}
function isERC721(Structs.Asset memory asset) public pure returns (bool) {
return (asset.assetType == Structs.AssetType.ERC721);
}
function isERC1155(Structs.Asset memory asset) public pure returns (bool) {
return (asset.assetType == Structs.AssetType.ERC1155);
}
function isNFT(Structs.Asset memory asset) public pure returns (bool) {
return isERC721(asset) || isERC1155(asset);
}
function isFungible(Structs.Asset memory asset) public pure returns (bool) {
return isSynth(asset) || isERC20(asset) || isNative(asset);
}
function isFungible(Structs.Market memory mkt) public pure returns (bool) {
return
(isERC20(mkt.base) || isSynth(mkt.base) || isNative(mkt.base)) &&
(isERC20(mkt.quote) || isSynth(mkt.quote) || isNative(mkt.quote));
}
function isInstantMarket(Structs.Market memory mkt) public pure returns (bool) {
return
((isERC20(mkt.base) && isERC20(mkt.quote)) ||
(isERC20(mkt.base) && isNFT(mkt.quote)) ||
(isERC20(mkt.base) && isNative(mkt.quote)) ||
(isNFT(mkt.base) && isERC20(mkt.quote)) ||
(isNFT(mkt.base) && isNFT(mkt.quote))) ||
(isNFT(mkt.base) && isNative(mkt.quote)) ||
(isNative(mkt.base) && isNative(mkt.quote)) ||
(isNative(mkt.base) && isERC20(mkt.quote)) ||
(isNative(mkt.base) && isNFT(mkt.quote));
}
function hasERC20OrNative(Structs.Market memory mkt) public pure returns (bool) {
return isERC20(mkt.base) || isERC20(mkt.quote) || isNative(mkt.base) || isNative(mkt.quote);
}
function isOnchain(Structs.Asset memory asset) public pure returns (bool) {
return isERC20(asset) || isNFT(asset) || isNative(asset);
}
function getPayer(Structs.Market memory mkt, Structs.Order storage o) public view returns (address) {
address payer;
if (isOnchain(mkt.base) && isSynth(mkt.quote)) {
payer = o.taker;
} else if (isSynth(mkt.base) && isSynth(mkt.quote)) {
payer = o.taker;
} else if (isSynth(mkt.base) && isOnchain(mkt.quote)) {
payer = o.provider;
}
return payer;
}
}
文件 28 的 44:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
文件 29 的 44:MathLib.sol
pragma solidity ^0.8.13;
library MathLib {
function sqrt(uint256 x) internal pure returns (uint256 y) {
uint256 z = (x + 1) / 2;
y = x;
while (z < y) {
y = z;
z = (x / z + z) / 2;
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b + (a % b == 0 ? 0 : 1);
}
}
文件 30 的 44:NonFungibleLiquidityLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "../token/interfaces/IERC721.sol";
import "../token/interfaces/IERC1155.sol";
import "../common/StrippedInterfaces.sol";
import "../common/MathLib.sol";
import "./AuxLib.sol";
import "../market/MarketAuxLib.sol";
import "./StructsLib.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../feepurse/interfaces/IFeePurse.sol";
import "./LiqAuxLib.sol";
library NonFungibleLiquidityLib {
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
using AuxLib for uint256[];
using AuxLib for Structs.Market;
using AuxLib for Structs.Liquidity;
using AuxLib for address;
event UpdatedNonFungibleLiquidity(
address indexed provider,
address indexed marketId,
address target,
bool deduct,
bool paused,
uint256 lid,
uint256[] ids,
uint256 price,
uint256[] wantOrIds,
uint256[] wantAndIds,
uint256 timeToPay
);
function updateNonFungibleLiquidity(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.UpdateLiquiditySlot memory slot
) external {
require(slot.deduct || s2.marketCore.isPutPermitted(slot.marketId, msg.sender));
Structs.Market memory mkt = s2.marketCore.getMarket(slot.marketId);
require(mkt.base.isNFT(), "OC: UNEXP_BASE");
require(!mkt.isInstantMarket() || slot.timeToPay == 0, "OC: TTP_NREQ");
require(slot.timeToPay == 0 || slot.timeToPay >= s1.minTimeToPay, "OC: LOW_TTP");
require(mkt.quote.isFungible() || slot.price == 0, "OC: PRICE_NREQ");
require(!mkt.quote.isFungible() || slot.price > 0, "OC: PRICE_REQ");
require(!mkt.quote.isFungible() || (slot.wantOrIds.length == 0 && slot.wantAndIds.length == 0), "OC: WANT_IDS_NREQ");
require(slot.wantOrIds.isUnique() && slot.wantAndIds.isUnique(), "OC: WANT_IDS_NUNIQ");
require(slot.wantOrIds.isMaxLen16() && slot.wantAndIds.isMaxLen16(), "OC: WANT_IDS_HSIZE");
require(slot.ids.isMaxLen16(), "OC: IDS_HSIZE");
require(slot.ids.isUnique(), "OC: IDS_NUNIQ");
LiqAuxLib.checkMarketPutBadges(s2, slot.marketId);
Structs.Liquidity storage liq;
if (AuxLib.isLiquidityExist(s1, slot.marketId, msg.sender, slot.lid)) {
liq = s1.liquidity[slot.marketId][msg.sender][slot.lid];
} else {
uint256[] memory zero = new uint256[](0);
s1.liquidity[slot.marketId][msg.sender].push(
Structs.Liquidity(zero, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, zero, zero, false, slot.target)
);
slot.lid = s1.liquidity[slot.marketId][msg.sender].length - 1;
liq = s1.liquidity[slot.marketId][msg.sender][slot.lid];
}
require(!liq.isLiquidityEmpty() || slot.ids.length > 0, "OC: REQ_IDS");
if (!slot.deduct) {
uint256 numIds = slot.ids.length;
mkt.numLiquidity += numIds;
for (uint256 i = 0; i < numIds; i++) {
liq.ids.push(slot.ids[i]);
if (mkt.base.isERC721()) {
IERC721(mkt.base.addr).transferFrom(msg.sender, address(this), slot.ids[i]);
} else {
IERC1155(mkt.base.addr).safeTransferFrom(msg.sender, address(this), slot.ids[i], 1, "");
}
}
if (!mkt.hasERC20OrNative()) {
LiqAuxLib.lockFeeForProtocol(s1, s2, mkt, liq, numIds);
LiqAuxLib.lockFeeForMarketCreator(s2, mkt, liq, numIds);
}
}
if (slot.deduct && slot.ids.length > 0) {
uint256 popped = 0;
for (uint256 i = 0; i < slot.ids.length; i++) {
if (slot.ids[i] - popped >= liq.ids.length) continue;
uint256 id = liq.ids[slot.ids[i] - popped];
liq.ids[slot.ids[i] - popped] = liq.ids[liq.ids.length - 1];
liq.ids.pop();
popped++;
if (mkt.base.isERC721()) {
IERC721(mkt.base.addr).transferFrom(address(this), msg.sender, id);
} else {
IERC1155(mkt.base.addr).safeTransferFrom(address(this), msg.sender, id, 1, "");
}
}
if (!mkt.hasERC20OrNative()) {
LiqAuxLib.unlockFeeForProtocol(s2, mkt, liq);
LiqAuxLib.unlockFeeForMarketCreator(s2, mkt, liq);
}
mkt.numLiquidity -= popped;
}
liq.timeToPay = slot.timeToPay;
liq.price = slot.price;
liq.wantAndIds = slot.wantAndIds;
liq.wantOrIds = slot.wantOrIds;
liq.target = slot.target;
liq.paused = slot.pause;
s2.marketCore.setCounters(slot.marketId, false, false, true, mkt.numLiquidity);
emit UpdatedNonFungibleLiquidity(
msg.sender,
slot.marketId,
slot.target,
slot.deduct,
slot.pause,
slot.lid,
slot.ids,
slot.price,
slot.wantOrIds,
slot.wantAndIds,
slot.timeToPay
);
}
}
文件 31 的 44:OfferLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../core/AuxLib.sol";
import "../core/SwapFungibleLib.sol";
import "../core/SwapNonFungibleLib.sol";
import "../core/StructsLib.sol";
import "../market/MarketAuxLib.sol";
import "../token/interfaces/IERC20.sol";
import "../common/StrippedInterfaces.sol";
library OfferLib {
using MarketAuxLib for Structs.Asset;
using AuxLib for uint256[];
event NewOffer(
address marketId,
address indexed provider,
uint256 lid,
address indexed offerer,
uint256 offerId,
uint256 amount,
uint256 price,
uint256[] ids,
uint256 expireDuration
);
event OfferUpdated(
uint256 indexed offerId,
address indexed offerer,
uint256 amount,
uint256 price,
uint256[] ids,
uint256 expireDuration
);
event OfferAccepted(uint256 indexed offerId, address indexed acceptor, uint256 execDelayDur);
event OfferUnaccepted(uint256 indexed offerId, address indexed unacceptor);
event OfferCancelled(uint256 indexed offerId, address indexed canceller);
event OfferExecuted(uint256 indexed offerId, address indexed executor);
struct CheckOfferAddresses {
address marketId;
address provider;
address recipient;
}
struct CheckOfferIntSlots {
uint256 lid;
uint256 amount;
uint256 price;
uint256 deadline;
uint256 offerId;
uint256 operator;
}
struct CheckOfferSlot {
CheckOfferAddresses addrs;
uint256[] ids;
CheckOfferIntSlots ints;
}
function checkOffer(StructsLib.State storage s1, StructsLib.State2 storage s2, CheckOfferSlot memory slot) public view {
require(AuxLib.hasNonZeroLiquidity(s1, slot.addrs.marketId, slot.addrs.provider, slot.ints.lid), "OC: ZERO_LIQ");
require(slot.ints.deadline > block.timestamp, "OC: PAST_DEADLINE");
Structs.Liquidity storage liq = s1.liquidity[slot.addrs.marketId][slot.addrs.provider][slot.ints.lid];
Structs.Market memory mkt = s2.marketCore.getMarket(slot.addrs.marketId);
StructsLib.SwapSlotAddresses memory addrs = StructsLib.SwapSlotAddresses(
slot.addrs.marketId,
slot.addrs.provider,
slot.addrs.recipient
);
StructsLib.SwapSlot memory ss = StructsLib.SwapSlot(
slot.ints.lid,
slot.ints.amount,
slot.ints.price,
slot.ids,
slot.ints.offerId,
slot.ints.operator,
addrs
);
if (mkt.base.isFungible()) AuxLib.checkFungibleSwapParams(ss, mkt, liq);
else AuxLib.checkNonFungibleSwapParams(ss, mkt, liq);
if (mkt.quote.isERC20() || mkt.quote.isNative()) {
uint256 cost;
if (mkt.base.isNFT()) cost = slot.ints.price;
else cost = (slot.ints.amount * slot.ints.price) / 10 ** ((mkt.base.isSynth()) ? 18 : IERC20(mkt.base.addr).decimals());
require(mkt.quote.isNative() || IERC20(mkt.quote.addr).balanceOf(msg.sender) >= cost, "OC: LOW_BAL");
require(!mkt.quote.isNative() || msg.sender.balance >= cost, "OC: LOW_BAL");
}
if (mkt.quote.isNFT()) {
uint256 n = slot.ids.length;
for (uint256 i = 0; i < n; i++) {
if (mkt.quote.isERC721()) require(IERC721Strip(mkt.quote.addr).ownerOf(slot.ids[i]) == msg.sender, "OC: NOT_TOK_OWNER");
else require(IERC1155Strip(mkt.quote.addr).balanceOf(msg.sender, slot.ids[i]) > 0, "OC: NOT_TOK_OWNER");
}
}
}
struct CreateOfferAddressParams {
address marketId;
address provider;
address recipient;
}
struct CreateOfferIntParams {
uint256 lid;
uint256 amount;
uint256 price;
uint256 expireDur;
uint256 operator;
}
function createOffer(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
CreateOfferAddressParams memory offerAddrs,
CreateOfferIntParams memory offerInts,
uint256[] memory ids
) public returns (uint256) {
CheckOfferAddresses memory addrs = CheckOfferAddresses(offerAddrs.marketId, offerAddrs.provider, offerAddrs.recipient);
CheckOfferIntSlots memory ints = CheckOfferIntSlots(
offerInts.lid,
offerInts.amount,
offerInts.price,
block.timestamp + offerInts.expireDur,
s2.offers.length + 1,
offerInts.operator
);
CheckOfferSlot memory slot = CheckOfferSlot(addrs, ids, ints);
checkOffer(s1, s2, slot);
s2.offers.push(
Structs.Offer(
msg.sender,
offerAddrs.marketId,
offerAddrs.provider,
offerAddrs.recipient,
offerInts.lid,
offerInts.amount,
offerInts.price,
ids,
0,
block.timestamp + offerInts.expireDur,
0,
offerInts.operator,
false,
false,
false
)
);
emit NewOffer(
offerAddrs.marketId,
offerAddrs.provider,
offerInts.lid,
msg.sender,
s2.offers.length,
offerInts.amount,
offerInts.price,
ids,
offerInts.expireDur
);
return s2.offers.length;
}
function updateOffer(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
uint256 offerId,
uint256 amount,
uint256 price,
uint256[] memory ids,
uint256 expireDur
) public {
require(offerId < s2.offers.length, "OC: UNKNOWN_OFFER");
Structs.Offer storage offer = s2.offers[offerId];
require(offer.creator == msg.sender, "OC: NOT_CREATOR");
require(offer.deadline > block.timestamp, "OC: OFFER_EXPIRED");
require(!offer.cancelled, "OC: OFFER_CANCELLED");
require(!offer.executed, "OC: OFFER_EXECUTED");
uint256 deadline = (expireDur == 0) ? offer.deadline : block.timestamp + expireDur;
checkOffer(
s1,
s2,
CheckOfferSlot(
CheckOfferAddresses(offer.marketId, offer.provider, offer.recipient),
ids,
CheckOfferIntSlots(offer.lid, amount, price, deadline, offerId + 1, offer.operator)
)
);
offer.amount = amount;
offer.price = price;
offer.ids = ids;
offer.deadline = deadline;
offer.accepted = false;
emit OfferUpdated(offerId, msg.sender, amount, price, ids, expireDur);
}
function acceptOffer(StructsLib.State2 storage s2, uint256 offerId, uint256 delay) public {
require(offerId < s2.offers.length, "OC: UNKNOWN_OFFER");
Structs.Offer storage offer = s2.offers[offerId];
require(offer.provider == msg.sender, "OC: NOT_PROVIDER");
require(offer.deadline > block.timestamp, "OC: OFFER_EXPIRED");
require(!offer.cancelled, "OC: OFFER_CANCELLED");
require(!offer.executed, "OC: OFFER_EXECUTED");
require(!offer.accepted, "OC: ALREADY_ACCEPTED");
offer.accepted = true;
offer.execAt = block.timestamp + delay;
emit OfferAccepted(offerId, msg.sender, delay);
}
function unacceptOffer(StructsLib.State2 storage s2, uint256 offerId) public {
require(offerId < s2.offers.length, "OC: UNKNOWN_OFFER");
Structs.Offer storage offer = s2.offers[offerId];
require(offer.provider == msg.sender, "OC: NOT_PROVIDER");
require(offer.accepted, "OC: NOT_ACCEPTED");
require(!offer.executed, "OC: OFFER_EXECUTED");
offer.accepted = false;
offer.execAt = 0;
emit OfferUnaccepted(offerId, msg.sender);
}
function cancelOffer(StructsLib.State2 storage s2, uint256 offerId) public {
require(offerId < s2.offers.length, "OC: UNKNOWN_OFFER");
Structs.Offer storage offer = s2.offers[offerId];
require(offer.creator == msg.sender, "OC: NOT_CREATOR");
require(offer.deadline > block.timestamp, "OC: OFFER_EXPIRED");
require(!offer.executed, "OC: OFFER_EXECUTED");
require(!offer.cancelled, "OC: ALREADY_CANCELLED");
offer.cancelled = true;
emit OfferCancelled(offerId, msg.sender);
}
function executeOffer(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
uint256 offerId
) public returns (Structs.Offer storage) {
require(offerId < s2.offers.length, "OC: UNKNOWN_OFFER");
Structs.Offer storage offer = s2.offers[offerId];
require(offer.creator == msg.sender, "OC: NOT_CREATOR");
require(offer.accepted, "OC: NOT_ACCEPTED");
require(!offer.executed, "OC: ALREADY_EXECUTED");
require(offer.execAt <= block.timestamp, "OC: DELAY_ACTIVE");
offer.executed = true;
Structs.Market memory mkt = s2.marketCore.getMarket(offer.marketId);
StructsLib.SwapSlotAddresses memory addrs = StructsLib.SwapSlotAddresses(offer.marketId, offer.provider, offer.recipient);
StructsLib.SwapSlot memory sp = StructsLib.SwapSlot(
offer.lid,
offer.amount,
offer.price,
offer.ids,
offerId + 1,
offer.operator,
addrs
);
emit OfferExecuted(offerId, msg.sender);
if (mkt.base.isFungible()) SwapFungibleLib.swap(s1, s2, sp, mkt);
else SwapNonFungibleLib.swap(s1, s2, sp, mkt);
return offer;
}
}
文件 32 的 44:OrderLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "../common/SigLib.sol";
import "./AuxLib.sol";
import "./StructsLib.sol";
import "../market/MarketAuxLib.sol";
import "./LiquidityLib.sol";
import {IERC721Strip, IERC1155Strip} from "../common/StrippedInterfaces.sol";
library OrderLib {
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
using AuxLib for address;
event SwapOrder(
address indexed mid,
address indexed provider,
address indexed swapper,
address recipient,
uint256[7] numTypeInfo,
uint256[] idsFromProvider,
uint256[] idsFromTaker
);
event OrderCancelled(uint256 indexed orderID, address indexed canceller, bool indexed byDispute);
event SwapOrderPaid(uint256 indexed orderID, address payer, uint256 disputeDelayDur);
event FinalizedByManagerSig(address manager, address finalizer, uint256 orderId, uint action);
function createOrder(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt,
Structs.Liquidity storage liq
) public {
require(liq.openOrders < s1.ints.maxOpenOrders, "OC: MAX_OPEN_ORDERS");
require(liq.openDisputes < s1.ints.maxOpenDisputes, "OC: MAX_OPEN_DISPUTES");
Structs.Order memory o;
o.offerId = sp.offerId;
o.amount = sp.amount;
o.price = (sp.offerId > 0) ? sp.maxPrice : liq.price;
if (mkt.quote.isNFT()) {
o.takerIds = (sp.offerId > 0) ? sp.ids : LiquidityLib.findMatchInWantIds(sp.ids, s2.intIdx, liq.wantOrIds, liq.wantAndIds);
require(o.takerIds.length > 0, "OC: NO_ID_MATCH");
for (uint256 i = 0; i < o.takerIds.length; i++) {
if (o.takerIds[i] == 0) continue;
if (mkt.quote.isERC721()) IERC721Strip(mkt.quote.addr).transferFrom(msg.sender, address(this), o.takerIds[i]);
else IERC1155Strip(mkt.quote.addr).safeTransferFrom(msg.sender, address(this), o.takerIds[i], 1, "");
}
}
if (mkt.quote.isERC20()) {
uint256 cost = (sp.amount * o.price) / 10 ** 18;
IERC20(mkt.quote.addr).transferFrom(msg.sender, address(this), cost);
} else if (mkt.quote.isNative()) {
uint256 cost = (sp.amount * o.price) / 10 ** 18;
require(msg.value >= cost, "OC: LOW_DEPOSIT");
}
uint256 deduction;
if (mkt.base.isNFT()) {
o.providerIds = liq.ids;
deduction = liq.ids.length;
delete liq.ids;
} else if (mkt.quote.isNFT()) {
o.amount = liq.amount;
deduction = o.amount;
liq.amount = 0;
} else if (sp.amount > 0) {
liq.amount -= sp.amount;
deduction = sp.amount;
}
uint256 timeToPay = (liq.timeToPay > 0) ? liq.timeToPay : s1.minTimeToPay;
o.marketId = sp.addrs.marketId;
o.provider = sp.addrs.provider;
o.operator = sp.operator;
o.lid = sp.lid;
o.taker = msg.sender;
o.recipient = sp.addrs.recipient;
o.createdAt = block.timestamp;
o.payDeadline = block.timestamp + timeToPay;
o.cancelAt = block.timestamp + timeToPay + s1.orderGraceDur;
s1.orders.push(o);
s1.numOrders++;
liq.openOrders += 1;
s2.marketCore.setCounters(sp.addrs.marketId, true, false, false, mkt.numOrders + 1);
s2.marketCore.setCounters(sp.addrs.marketId, false, false, true, mkt.numLiquidity - deduction);
emit SwapOrder(
sp.addrs.marketId,
sp.addrs.provider,
msg.sender,
sp.addrs.recipient,
[s1.numOrders - 1, sp.lid, sp.amount, o.price, sp.offerId, sp.operator, timeToPay + s1.orderGraceDur],
o.providerIds,
o.takerIds
);
}
function cancelOrderByManagerSig(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
address owner,
uint256 oid,
uint256 expireAt,
bytes calldata signature
) public {
Structs.Market memory mkt = s2.marketCore.getMarket(s1.orders[oid].marketId);
require(mkt.manager != address(0), "OC: NO_MGR_SET");
require(expireAt > block.timestamp, "OC: EXPIRED_SIG");
require(verifyMarketManagerSig(mkt.manager, oid, 2, expireAt, signature), "OC: BAD_SIG");
cancelOrder(s1, s2, owner, oid, false, true);
emit FinalizedByManagerSig(mkt.manager, msg.sender, oid, 2);
}
function cancelOrder(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
address owner,
uint256 id,
bool byDispute,
bool byManager
) public {
Structs.Order storage o = s1.orders[id];
Structs.Market memory mkt = s2.marketCore.getMarket(o.marketId);
require(
byDispute ||
byManager ||
o.provider == msg.sender ||
o.taker == msg.sender ||
mkt.manager == msg.sender ||
s2.minerReg.isMiner(msg.sender) ||
owner == msg.sender,
"OC: NOT_AUTHORIZED"
);
require(byDispute || (!o.paid && !o.released && !o.disputed && !o.cancelled), "OC: NOT_INACTIVE");
require(byDispute || o.cancelAt <= block.timestamp, "OC: NOT_CANCEL_TIME");
Structs.Liquidity storage liq = s1.liquidity[o.marketId][o.provider][o.lid];
if (mkt.isFungible() && mkt.hasERC20OrNative()) {
liq.amount += o.amount;
s2.marketCore.setCounters(o.marketId, false, false, true, mkt.numLiquidity + o.amount);
if (mkt.quote.isERC20()) {
uint256 cost = (o.amount * o.price) / 10 ** 18;
IERC20(mkt.quote.addr).transfer(o.taker, cost);
}
if (mkt.quote.isNative()) {
uint256 cost = (o.amount * o.price) / 10 ** 18;
payable(o.taker).transfer(cost);
}
}
if (mkt.base.isSynth() && mkt.quote.isSynth()) {
liq.amount += o.amount;
s2.marketCore.setCounters(o.marketId, false, false, true, mkt.numLiquidity + o.amount);
}
if (mkt.base.isSynth() && mkt.quote.isNFT()) {
liq.amount += o.amount;
s2.marketCore.setCounters(o.marketId, false, false, true, mkt.numLiquidity + o.amount);
for (uint256 i = 0; i < o.takerIds.length; i++) {
if (mkt.quote.isERC721()) IERC721Strip(mkt.quote.addr).transferFrom(address(this), o.taker, o.takerIds[i]);
else IERC1155Strip(mkt.quote.addr).safeTransferFrom(address(this), o.taker, o.takerIds[i], 1, "");
}
}
if (mkt.base.isNFT() && mkt.quote.isSynth()) {
liq.ids = o.providerIds;
s2.marketCore.setCounters(o.marketId, false, false, true, mkt.numLiquidity + liq.ids.length);
}
liq.openOrders -= 1;
o.cancelled = true;
o.finalizer = msg.sender;
if (s2.minerReg.isMiner(msg.sender)) {
s2.minerReg.addReward(MinerOperation.Cancel, msg.sender);
}
emit OrderCancelled(id, msg.sender, byDispute);
}
function markOrderAsPaidByManagerSig(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
uint256 oid,
uint256 expireAt,
bytes calldata signature
) public {
Structs.Market memory mkt = s2.marketCore.getMarket(s1.orders[oid].marketId);
require(mkt.manager != address(0), "OC: NO_MGR_SET");
require(expireAt > block.timestamp, "OC: EXPIRED_SIG");
require(verifyMarketManagerSig(mkt.manager, oid, 0, expireAt, signature), "OC: BAD_SIG");
markOrderAsPaid(s1, s2.marketCore, oid, true);
emit FinalizedByManagerSig(mkt.manager, msg.sender, oid, 0);
}
function markOrderAsPaid(StructsLib.State storage s1, IMarketCore marketCore, uint256 id, bool byManager) public {
require(AuxLib.hasOrder(s1, id), "OC: UNKNOWN_ORDER");
Structs.Order storage o = s1.orders[id];
require(!o.released && !o.cancelled && !o.paid, "OC: NOT_ACTIVE");
Structs.Market memory market = marketCore.getMarket(o.marketId);
require(byManager || msg.sender == MarketAuxLib.getPayer(market, o), "OC: NOT_PAYER");
o.paid = true;
o.disputeFrom = block.timestamp + market.dur.disputeDelayDur;
emit SwapOrderPaid(id, byManager ? market.manager : msg.sender, market.dur.disputeDelayDur);
}
function markAsDisputed(StructsLib.State storage s1, IMarketCore marketCore, uint256 id) public {
Structs.Order storage o = s1.orders[id];
o.disputed = true;
Structs.Market memory m = marketCore.getMarket(o.marketId);
m.numDisputes++;
marketCore.setCounters(o.marketId, false, true, false, m.numDisputes);
}
function verifyMarketManagerSig(
address signer,
uint256 id,
uint action,
uint256 expireAt,
bytes memory signature
) internal view returns (bool) {
if (address(0) == signer) return false;
bytes32 messageHash = keccak256(abi.encode(block.chainid, id, action, expireAt));
bytes32 ethSignedMessageHash = SigLib.getSignedMessageHash(messageHash);
return SigLib.recoverSigner(ethSignedMessageHash, signature) == signer;
}
}
文件 33 的 44:OrderReleaseLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "../common/SigLib.sol";
import "./AuxLib.sol";
import "./StructsLib.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "../market/MarketAuxLib.sol";
import "./LiquidityLib.sol";
import "./FeeLib.sol";
import {IERC721Strip, IERC1155Strip} from "../common/StrippedInterfaces.sol";
library OrderReleaseLib {
using MarketAuxLib for Structs.Asset;
using MarketAuxLib for Structs.Market;
using AuxLib for address;
event Swap(
address indexed mid,
address indexed provider,
address indexed swapper,
address recipient,
address releaser,
uint256[6] numTypeInfo,
bool byDispute,
uint256[] idsFromProvider,
uint256[] idsFromTaker
);
event FinalizedByManagerSig(address manager, address finalizer, uint256 orderId, uint action);
function releaseOrderByManagerSig(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
address owner,
uint256 oid,
uint256 expireAt,
bytes calldata signature
) public {
Structs.Market memory mkt = s2.marketCore.getMarket(s1.orders[oid].marketId);
require(mkt.manager != address(0), "OC: NO_MGR_SET");
require(expireAt > block.timestamp, "OC: EXPIRED_SIG");
require(verifyMarketManagerSig(mkt.manager, oid, 1, expireAt, signature), "OC: BAD_SIG");
releaseOrder(s1, s2, owner, oid, false, true);
emit FinalizedByManagerSig(mkt.manager, msg.sender, oid, 1);
}
function releaseOrder(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
address owner,
uint256 oid,
bool byDispute,
bool byManager
) public {
Structs.Order storage o = s1.orders[oid];
require(!o.cancelled && !o.released, "OC: ALREADY_FINALIZED");
Structs.Market memory mkt = s2.marketCore.getMarket(o.marketId);
address releaser = (byDispute)
? msg.sender
: (byManager)
? mkt.manager
: (o.taker == MarketAuxLib.getPayer(mkt, o))
? o.provider
: o.taker;
require(byDispute || byManager || msg.sender == releaser || msg.sender == owner, "OC: NOT_RELEASER");
require(o.paid, "OC: ORDER_UNPAID");
Structs.Asset memory asset;
if (mkt.isFungible() && mkt.hasERC20OrNative()) {
asset = releaseForFungibles(s1, s2, o, mkt);
}
if (mkt.base.isSynth() && mkt.quote.isSynth()) {
asset = releaseForSynthToSynthOrNFT(s1, s2, o, mkt);
}
if (mkt.base.isSynth() && mkt.quote.isNFT()) {
asset = releaseForSynthToNFT(s1, s2, o, mkt);
}
if (mkt.base.isNFT() && mkt.quote.isSynth()) {
asset = releaseForNFTToSynth(s1, s2, o, mkt);
}
o.released = true;
o.finalizer = releaser;
s1.liquidity[o.marketId][o.provider][o.lid].openOrders -= 1;
emit Swap(
o.marketId,
o.provider,
o.taker,
o.recipient,
releaser,
[oid + 1, o.lid, o.amount, o.price, o.offerId, o.operator],
byDispute,
o.providerIds,
o.takerIds
);
}
function releaseForSynthToNFT(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
Structs.Order storage o,
Structs.Market memory mkt
) internal returns (Structs.Asset memory asset) {
asset = releaseForSynthToSynthOrNFT(s1, s2, o, mkt);
for (uint256 i = 0; i < o.takerIds.length; i++) {
if (mkt.quote.isERC721()) IERC721Strip(mkt.quote.addr).transferFrom(address(this), o.provider, o.takerIds[i]);
else IERC1155Strip(mkt.quote.addr).safeTransferFrom(address(this), o.provider, o.takerIds[i], 1, "");
}
return asset;
}
struct BoolSlot {
bool sharable;
bool isOperator;
}
function releaseForNFTToSynth(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
Structs.Order storage o,
Structs.Market memory mkt
) internal returns (Structs.Asset memory asset) {
Structs.Liquidity storage liq = s1.liquidity[o.marketId][o.provider][o.lid];
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
o.lid,
o.amount,
o.price,
s2.nft,
o.provider,
o.taker
)
);
s2.feePurse.unlock(o.provider, liq.protoFeePurseId);
s2.feePurse.unlock(o.provider, liq.mktCreatorFeePurseId);
liq.protoFeePurseId = 0;
liq.mktCreatorFeePurseId = 0;
s2.feePurse.transferFrom(o.provider, mkt.creator, feeInfo.mktCreatorFee);
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, mkt.base.addr), s2.operatorMgr.isOperator(o.operator));
if (bools.sharable) {
s2.feePurse.transferFrom(o.provider, address(this), (feeInfo.protoFee * s1.feeBPs[1]) / 10000);
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
address opAddr = s2.operatorMgr.getOperator(o.operator);
s2.feePurse.transferFrom(o.provider, opAddr, (feeInfo.protoFee * s1.feeBPs[2]) / 10000);
totalFeeBps -= s1.feeBPs[2];
}
s2.feePurse.transferFrom(o.provider, s1.inventor, (feeInfo.protoFee * totalFeeBps) / 10000);
for (uint256 i = 0; i < o.providerIds.length; i++)
if (mkt.base.isERC721())
IERC721Strip(mkt.base.addr).transferFrom(address(this), o.recipient.setOrDef(o.taker), o.providerIds[i]);
else IERC1155Strip(mkt.base.addr).safeTransferFrom(address(this), o.recipient.setOrDef(o.taker), o.providerIds[i], 1, "");
return mkt.base;
}
struct IntSlot {
uint256 remaining;
uint256 protoFeeRate;
uint256 mktCreatorFeeRate;
uint256 protoFee;
uint256 mktCreatorFee;
}
function releaseForSynthToSynthOrNFT(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
Structs.Order memory o,
Structs.Market memory mkt
) internal returns (Structs.Asset memory asset) {
Structs.Liquidity storage liq = s1.liquidity[o.marketId][o.provider][o.lid];
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
o.lid,
o.amount,
o.price,
s2.nft,
o.provider,
o.taker
)
);
s2.feePurse.unlock(o.provider, liq.protoFeePurseId);
s2.feePurse.unlock(o.provider, liq.mktCreatorFeePurseId);
s2.feePurse.transferFrom(o.provider, mkt.creator, feeInfo.mktCreatorFee);
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, asset.addr), s2.operatorMgr.isOperator(o.operator));
if (bools.sharable) {
s2.feePurse.transferFrom(o.provider, address(this), (feeInfo.protoFee * s1.feeBPs[1]) / 10000);
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
address opAddr = s2.operatorMgr.getOperator(o.operator);
s2.feePurse.transferFrom(o.provider, opAddr, (feeInfo.protoFee * s1.feeBPs[2]) / 10000);
totalFeeBps -= s1.feeBPs[2];
}
s2.feePurse.transferFrom(o.provider, s1.inventor, (feeInfo.protoFee * totalFeeBps) / 10000);
liq.protoFeePurseId = s2.feePurse.lock(o.provider, (feeInfo.protoFeeRate * feeInfo.remaining) / 10 ** 18);
liq.mktCreatorFeePurseId = s2.feePurse.lock(o.provider, (feeInfo.mktCreatorFeeRate * feeInfo.remaining) / 10 ** 18);
return mkt.base;
}
function releaseForFungibles(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
Structs.Order storage o,
Structs.Market memory mkt
) internal returns (Structs.Asset memory asset) {
asset = mkt.base.isOnchain() ? mkt.base : mkt.quote;
Structs.Liquidity memory liq = s1.liquidity[o.marketId][o.provider][o.lid];
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
o.lid,
o.amount,
o.price,
s2.nft,
o.provider,
o.taker
)
);
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
s1.feeBalance[mkt.creator][asset.addr] += feeInfo.mktCreatorFee;
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, asset.addr), s2.operatorMgr.isOperator(o.operator));
if (bools.sharable) {
s1.shareablesBalance[asset.addr] += (feeInfo.protoFee * s1.feeBPs[1]) / 10000;
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
s1.operatorsBalance[s2.operatorMgr.getOperator(o.operator)][asset.addr] += (feeInfo.protoFee * s1.feeBPs[2]) / 10000;
totalFeeBps -= s1.feeBPs[2];
}
s1.inventorBalance[asset.addr] += (feeInfo.protoFee * totalFeeBps) / 10000;
address receiver = (!mkt.base.isSynth()) ? o.taker : o.provider;
if (asset.isERC20()) {
IERC20(asset.addr).transfer(o.recipient.setOrDef(receiver), feeInfo.amtToCharge - feeInfo.totalFees);
} else if (asset.isNative()) {
payable(o.recipient.setOrDef(receiver)).transfer(feeInfo.amtToCharge - feeInfo.totalFees);
}
return asset;
}
function verifyMarketManagerSig(
address signer,
uint256 id,
uint action,
uint256 expireAt,
bytes memory signature
) internal view returns (bool) {
if (address(0) == signer) return false;
bytes32 messageHash = keccak256(abi.encode(block.chainid, id, action, expireAt));
bytes32 ethSignedMessageHash = SigLib.getSignedMessageHash(messageHash);
return SigLib.recoverSigner(ethSignedMessageHash, signature) == signer;
}
}
文件 34 的 44:Ownable.sol
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/utils/Context.sol";
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "OWNABLE: NOT_OWNER");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "INVALID_ADDRESS");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 35 的 44:SafeERC20.sol
pragma solidity ^0.8.4;
import "../token/interfaces/IERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 36 的 44:SigLib.sol
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
library SigLib {
function getSignedMessageHash(bytes32 _messageHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash));
}
function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) internal pure returns (address) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);
(address addr, ) = ECDSA.tryRecover(_ethSignedMessageHash, v, r, s);
return addr;
}
function splitSignature(bytes memory sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
require(sig.length == 65, "invalid signature length");
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
}
}
文件 37 的 44:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
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), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
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) {
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] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 38 的 44:StrippedInterfaces.sol
pragma solidity ^0.8.13;
interface IERC721Strip {
function balanceOf(address owner) external view returns (uint256 balance);
function transferFrom(address from, address to, uint256 tokenId) external;
function ownerOf(uint256 _tokenId) external view returns (address);
}
interface IERC1155Strip {
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
function balanceOf(address _owner, uint256 _id) external view returns (uint256);
}
文件 39 的 44:Structs.sol
pragma solidity ^0.8.13;
library Structs {
enum AssetType {
SYNTH,
ERC20,
ERC721,
ERC1155,
NATIVE
}
struct Asset {
address addr;
AssetType assetType;
}
struct MarketDur {
uint256 disputeDelayDur;
}
struct Market {
uint256 createdAt;
uint256 numOrders;
uint256 numDisputes;
uint256 numLiquidity;
uint256 commission;
uint256 poolId;
MarketDur dur;
address creator;
address manager;
Asset base;
Asset quote;
MarketPerms perms;
}
struct MarketPerms {
bool put;
bool swap;
bool offerOnly;
bool allowZeroOfferPrice;
}
struct Liquidity {
uint256[] ids;
uint256 amount;
uint256 price;
uint256 minSwap;
uint256 maxSwap;
uint256 timeToPay;
uint256 openOrders;
uint256 openDisputes;
uint256 protoFeePurseId;
uint256 mktCreatorFeePurseId;
uint256 protoFeeRate;
uint256 mktCreatorFeeRate;
uint256[] wantOrIds;
uint256[] wantAndIds;
bool paused;
address target;
}
struct Order {
address marketId;
address provider;
address taker;
address recipient;
address finalizer;
uint256 lid;
uint256 amount;
uint256 price;
uint256 createdAt;
uint256 payDeadline;
uint256 cancelAt;
uint256 disputeFrom;
uint256 offerId;
uint256 operator;
uint256[] takerIds;
uint256[] providerIds;
bool paid;
bool released;
bool disputed;
bool cancelled;
}
struct Offer {
address creator;
address marketId;
address provider;
address recipient;
uint256 lid;
uint256 amount;
uint256 price;
uint256[] ids;
uint256 liq;
uint256 deadline;
uint256 execAt;
uint256 operator;
bool accepted;
bool cancelled;
bool executed;
}
struct Mediator {
address addr;
uint256 bond;
uint256 bondReleaseAt;
uint256 matureAt;
}
struct TicketStatus {
bool drafted;
bool joined;
bool blocked;
bool slashed;
bool paused;
}
struct Ticket {
uint256 idx;
uint256 poolId;
uint256 bond;
uint256 matureAt;
int256 poolIdx;
uint256 cancelAt;
uint256 joinBy;
uint256 numPaused;
address owner;
TicketStatus status;
}
struct TicketPool {
bool exists;
bool approvedMediatorOnly;
bool approvedMarketOnly;
uint256 reqBond;
uint256 draftReward;
uint256 winReward;
uint256 noVoteSlashBP;
uint256 loseVoteSlashBP;
uint256 numDraftees;
uint256 evidenceDur;
uint256 predictDur;
}
struct DelegateTicket {
address owner;
uint256 id;
}
struct PoolTicket {
address owner;
uint256 idx;
}
struct PurchaseWindow {
uint256 endTime;
uint256 numPurchases;
uint256 supply;
uint256 price;
}
}
文件 40 的 44:StructsLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../assetregistry/interfaces/IAssetRegistry.sol";
import "../token/interfaces/IERC20.sol";
import "../market/interfaces/IMarketCore.sol";
import "../pools/interfaces/IFeePool.sol";
import "../feepurse/interfaces/IFeePurse.sol";
import "../badge/interfaces/IBadge.sol";
import "../operator/interfaces/IOperator.sol";
import "../minerregisty/interfaces/IMinerRegistry.sol";
library StructsLib {
struct UserRewardLog {
uint256 phase;
uint256 period;
}
struct IntSlotState {
uint256 instantSwapFeeBp;
uint256 synthSwapFeeBp;
uint256 stableSwapFeeBp;
uint256 instantNFTSwapFeeBp;
uint256 fixedSynthSwapFee;
uint256 fixedNFTSwapFee;
uint256 maxOpenOrders;
uint256 maxOpenDisputes;
}
struct State {
IntSlotState ints;
uint256[3] feeBPs;
uint256 minTimeToPay;
uint256 orderGraceDur;
uint256 numOrders;
uint256 feePoolTxInterval;
address inventor;
address ammSwapRouter;
Structs.Order[] orders;
UserRewardLog[] skipped;
mapping(address => mapping(address => uint256)) feeBalance;
mapping(address => uint256) shareablesBalance;
mapping(address => uint256) inventorBalance;
mapping(address => mapping(address => uint256)) operatorsBalance;
mapping(address => mapping(address => Structs.Liquidity[])) liquidity;
mapping(address => mapping(address => address)) liqManagers;
mapping(address => uint256) rewards;
mapping(address => uint256) lastFeePoolTransfer;
}
struct UintSlotState2 {
uint256 nftDiscountBp;
uint256 ammEthPoolFee;
}
struct State2 {
UintSlotState2 ints;
address disputeManager;
address nft;
address ammEth;
IAssetRegistry assetReg;
IERC20 token;
IMarketCore marketCore;
IFeePool feePool;
IFeePurse feePurse;
IBadge badge;
IOperator operatorMgr;
IMinerRegistry minerReg;
Structs.Offer[] offers;
mapping(address => mapping(address => mapping(uint256 => string[2][]))) reqSwapBadges;
mapping(address => AmmSwapPoolInfo) ammSwapPool;
mapping(uint256 => bool) intIdx;
}
struct AmmSwapPoolInfo {
address outAddr;
uint256 poolFee;
}
struct SwapSlotAddresses {
address marketId;
address provider;
address recipient;
}
struct SwapSlot {
uint256 lid;
uint256 amount;
uint256 maxPrice;
uint256[] ids;
uint256 offerId;
uint256 operator;
SwapSlotAddresses addrs;
}
struct UpdateLiquiditySlot {
address marketId;
uint256 lid;
bool deduct;
bool pause;
uint256 amount;
uint256[] ids;
uint256[] wantOrIds;
uint256[] wantAndIds;
uint256 price;
uint256 minSwap;
uint256 maxSwap;
uint256 timeToPay;
address target;
}
}
文件 41 的 44:SwapFungibleLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "./AuxLib.sol";
import "./StructsLib.sol";
import "../market/MarketAuxLib.sol";
import "./OrderLib.sol";
import {IERC1155Strip} from "../common/StrippedInterfaces.sol";
import "./LiquidityLib.sol";
import "./FeeLib.sol";
library SwapFungibleLib {
using SafeERC20 for IERC20;
using AuxLib for uint256[];
using AuxLib for address;
using MarketAuxLib for Structs.Asset;
event Swap(
address indexed mid,
address indexed provider,
address indexed swapper,
address recipient,
address releaser,
uint256[6] numTypeInfo,
bool byDispute,
uint256[] idsFromProvider,
uint256[] idsFromTaker
);
function swap(
StructsLib.State storage state,
StructsLib.State2 storage state2,
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt
) public {
require(AuxLib.hasNonZeroLiquidity(state, sp.addrs.marketId, sp.addrs.provider, sp.lid), "OC: ZERO_LIQ");
Structs.Liquidity storage liq = state.liquidity[sp.addrs.marketId][sp.addrs.provider][sp.lid];
require(liq.target.isZero() || liq.target == msg.sender, "OC: NOT_TARGET");
AuxLib.checkFungibleSwapParams(sp, mkt, liq);
require(sp.operator == 0 || state2.operatorMgr.isOperator(sp.operator), "OC: UNKNOWN_OPERATOR");
if (
(mkt.base.isERC20() && (mkt.quote.isERC20() || mkt.quote.isNative())) ||
(mkt.base.isNative() && (mkt.quote.isERC20() || mkt.quote.isNative()))
) {
return swapERC20OrNativeForERC20OrNative(state, state2, sp, mkt, liq);
}
if ((mkt.base.isERC20() || mkt.base.isNative()) && mkt.quote.isNFT()) {
return swapNFTForERC20OrNative(state, state2, sp, mkt, liq);
}
OrderLib.createOrder(state, state2, sp, mkt, liq);
}
struct BoolSlot {
bool sharable;
bool isOperator;
}
function swapERC20OrNativeForERC20OrNative(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt,
Structs.Liquidity storage liq
) public {
uint256 price = (sp.offerId > 0) ? sp.maxPrice : liq.price;
uint256 cost = (sp.amount * price) / 10 ** ((mkt.base.isERC20()) ? IERC20(mkt.base.addr).decimals() : 18);
require(!mkt.quote.isERC20() || IERC20(mkt.quote.addr).balanceOf(msg.sender) >= cost, "OC: LOW_QUOTE_BAL");
require(!mkt.quote.isNative() || msg.value >= cost, "OC: LOW_QUOTE_BAL");
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
sp.lid,
sp.amount,
price,
s2.nft,
sp.addrs.provider,
msg.sender
)
);
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
s1.feeBalance[mkt.creator][mkt.base.addr] += feeInfo.mktCreatorFee;
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, mkt.base.addr), s2.operatorMgr.isOperator(sp.operator));
if (bools.sharable) {
s1.shareablesBalance[mkt.base.addr] += (feeInfo.protoFee * s1.feeBPs[1]) / 10000;
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
s1.operatorsBalance[s2.operatorMgr.getOperator(sp.operator)][mkt.base.addr] += (feeInfo.protoFee * s1.feeBPs[2]) / 10000;
totalFeeBps -= s1.feeBPs[2];
}
s1.inventorBalance[mkt.base.addr] += (feeInfo.protoFee * totalFeeBps) / 10000;
liq.amount -= sp.amount;
s2.marketCore.setCounters(sp.addrs.marketId, false, false, true, mkt.numLiquidity - sp.amount);
if (mkt.quote.isERC20()) {
IERC20(mkt.quote.addr).safeTransferFrom(msg.sender, sp.addrs.provider, cost);
} else if (mkt.quote.isNative()) {
payable(sp.addrs.provider).transfer(cost);
}
if (mkt.base.isERC20()) {
IERC20(mkt.base.addr).safeTransfer(sp.addrs.recipient.setOrDef(msg.sender), sp.amount - feeInfo.totalFees);
} else if (mkt.base.isNative()) {
payable(sp.addrs.recipient.setOrDef(msg.sender)).transfer(sp.amount - feeInfo.totalFees);
}
emit Swap(
sp.addrs.marketId,
sp.addrs.provider,
msg.sender,
sp.addrs.recipient,
address(0),
[0, sp.lid, sp.amount, price, sp.offerId, sp.operator],
false,
new uint256[](0),
new uint256[](0)
);
}
function swapNFTForERC20OrNative(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt,
Structs.Liquidity storage liq
) public {
uint256[] memory matchIds = (sp.offerId > 0)
? sp.ids
: LiquidityLib.findMatchInWantIds(sp.ids, s2.intIdx, liq.wantOrIds, liq.wantAndIds);
require(matchIds.length > 0, "OC: NO_ID_MATCH");
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
sp.lid,
sp.amount,
0,
s2.nft,
sp.addrs.provider,
msg.sender
)
);
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
s1.feeBalance[mkt.creator][mkt.base.addr] += feeInfo.mktCreatorFee;
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, mkt.base.addr), s2.operatorMgr.isOperator(sp.operator));
if (bools.sharable) {
s1.shareablesBalance[mkt.base.addr] += (feeInfo.protoFee * s1.feeBPs[1]) / 10000;
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
s1.operatorsBalance[s2.operatorMgr.getOperator(sp.operator)][mkt.base.addr] += (feeInfo.protoFee * s1.feeBPs[2]) / 10000;
totalFeeBps -= s1.feeBPs[2];
}
s1.inventorBalance[mkt.base.addr] += (feeInfo.protoFee * totalFeeBps) / 10000;
if (mkt.base.isERC20()) {
IERC20(mkt.base.addr).safeTransfer(sp.addrs.recipient.setOrDef(msg.sender), liq.amount - feeInfo.totalFees);
} else if (mkt.base.isNative()) {
payable(sp.addrs.recipient.setOrDef(msg.sender)).transfer(liq.amount - feeInfo.totalFees);
}
for (uint256 i = 0; i < matchIds.length; i++) {
if (matchIds[i] == 0) continue;
if (mkt.quote.isERC721()) IERC721Strip(mkt.quote.addr).transferFrom(msg.sender, sp.addrs.provider, matchIds[i]);
else IERC1155Strip(mkt.quote.addr).safeTransferFrom(msg.sender, sp.addrs.provider, matchIds[i], 1, "");
}
s2.marketCore.setCounters(sp.addrs.marketId, false, false, true, mkt.numLiquidity - liq.amount);
liq.amount = 0;
emit Swap(
sp.addrs.marketId,
sp.addrs.provider,
msg.sender,
sp.addrs.recipient,
address(0),
[0, sp.lid, sp.amount, liq.price, sp.offerId, sp.operator],
false,
new uint256[](0),
matchIds
);
}
}
文件 42 的 44:SwapLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "./AuxLib.sol";
import "./StructsLib.sol";
import "../market/MarketAuxLib.sol";
import "../common/StrippedInterfaces.sol";
import "./OrderLib.sol";
import "./OrderReleaseLib.sol";
import "./SwapFungibleLib.sol";
import "./SwapNonFungibleLib.sol";
library SwapLib {
using MarketAuxLib for Structs.Asset;
function swapQuoteForBase(StructsLib.State storage state, StructsLib.State2 storage state2, StructsLib.SwapSlot memory sp) public {
require(state2.marketCore.isPutPermitted(sp.addrs.marketId, sp.addrs.provider));
require(state2.marketCore.isSwapPermitted(sp.addrs.marketId, msg.sender));
Structs.Market memory market = state2.marketCore.getMarket(sp.addrs.marketId);
require(!market.perms.offerOnly, "OC: OFFER_ONLY");
checkMarketSwapBadges(state2, sp.addrs.marketId);
checkProviderSwapBadges(state2, sp.addrs.marketId, sp.lid, sp.addrs.provider);
if (market.base.isFungible()) SwapFungibleLib.swap(state, state2, sp, market);
else SwapNonFungibleLib.swap(state, state2, sp, market);
}
function createOrder(
StructsLib.State storage state,
StructsLib.State2 storage state2,
StructsLib.SwapSlot memory sp,
Structs.Market memory market,
Structs.Liquidity storage liq
) public {
OrderLib.createOrder(state, state2, sp, market, liq);
}
function releaseOrder(
StructsLib.State storage state,
StructsLib.State2 storage state2,
address owner,
uint256 oid,
bool byDispute
) public {
OrderReleaseLib.releaseOrder(state, state2, owner, oid, byDispute, false);
}
function releaseOrderByManagerSig(
StructsLib.State storage state,
StructsLib.State2 storage state2,
address owner,
uint256 oid,
uint256 expireAt,
bytes calldata signature
) public {
OrderReleaseLib.releaseOrderByManagerSig(state, state2, owner, oid, expireAt, signature);
}
function cancelOrder(
StructsLib.State storage state,
StructsLib.State2 storage state2,
address owner,
uint256 id,
bool byDispute
) public {
OrderLib.cancelOrder(state, state2, owner, id, byDispute, false);
}
function cancelOrderByManagerSig(
StructsLib.State storage state,
StructsLib.State2 storage state2,
address owner,
uint256 oid,
uint256 expireAt,
bytes calldata signature
) external {
OrderLib.cancelOrderByManagerSig(state, state2, owner, oid, expireAt, signature);
}
function markOrderAsPaid(StructsLib.State storage state, IMarketCore marketCore, uint256 id, bool byManager) public {
OrderLib.markOrderAsPaid(state, marketCore, id, byManager);
}
function markOrderAsPaidByManagerSig(
StructsLib.State storage state,
StructsLib.State2 storage state2,
uint256 oid,
uint256 expireAt,
bytes calldata signature
) external {
OrderLib.markOrderAsPaidByManagerSig(state, state2, oid, expireAt, signature);
}
function markAsDisputed(StructsLib.State storage state, IMarketCore marketCore, uint256 id) public {
OrderLib.markAsDisputed(state, marketCore, id);
}
function checkMarketSwapBadges(StructsLib.State2 storage s2, address marketId) internal view {
(, string[2][] memory reqSwapBadges) = s2.marketCore.getReqBadges(marketId);
if (reqSwapBadges.length > 0) {
uint256 len = reqSwapBadges.length;
for (uint256 i = 0; i < len; i++) {
require(s2.badge.hasBadge(msg.sender, reqSwapBadges[i][0], reqSwapBadges[i][1]), "OC: MKT_BADGE_REQ");
}
}
}
function checkProviderSwapBadges(StructsLib.State2 storage s2, address marketId, uint256 lid, address provider) internal view {
string[2][] memory reqSwapBadges = s2.reqSwapBadges[marketId][provider][lid];
if (reqSwapBadges.length > 0) {
uint256 len = reqSwapBadges.length;
for (uint256 i = 0; i < len; i++) {
require(s2.badge.hasBadge(msg.sender, reqSwapBadges[i][0], reqSwapBadges[i][1]), "OC: LP_BADGE_REQ");
}
}
}
}
文件 43 的 44:SwapNonFungibleLib.sol
pragma solidity ^0.8.13;
import "../common/Structs.sol";
import "../market/interfaces/IMarketCore.sol";
import "../common/SafeERC20.sol";
import "./AuxLib.sol";
import "./StructsLib.sol";
import "../market/MarketAuxLib.sol";
import "./OrderLib.sol";
import {IERC1155Strip} from "../common/StrippedInterfaces.sol";
import "./FeeLib.sol";
library SwapNonFungibleLib {
using SafeERC20 for IERC20;
using MarketAuxLib for Structs.Asset;
using AuxLib for address;
event Swap(
address indexed mid,
address indexed provider,
address indexed swapper,
address recipient,
address releaser,
uint256[6] numTypeInfo,
bool byDispute,
uint256[] idsFromProvider,
uint256[] idsFromTaker
);
function swap(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.SwapSlot memory sp,
Structs.Market memory market
) public {
require(AuxLib.hasNonZeroLiquidity(s1, sp.addrs.marketId, sp.addrs.provider, sp.lid), "OC: ZERO_LIQ");
Structs.Liquidity storage liq = s1.liquidity[sp.addrs.marketId][sp.addrs.provider][sp.lid];
require(liq.target.isZero() || liq.target == msg.sender, "OC: NOT_TARGET");
AuxLib.checkNonFungibleSwapParams(sp, market, liq);
require(sp.operator == 0 || s2.operatorMgr.isOperator(sp.operator), "OC: UNKNOWN_OPERATOR");
if (market.quote.isERC20() || market.quote.isNative()) {
return swapERC20OrNativeForNFT(s1, s2, sp, market, liq);
}
if (market.quote.isNFT()) {
return swapNFTForNFT(s1, s2, sp, market, liq);
}
OrderLib.createOrder(s1, s2, sp, market, liq);
}
struct BoolSlot {
bool sharable;
bool isOperator;
}
function swapNFTForNFT(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt,
Structs.Liquidity storage liq
) public {
address sdr = msg.sender;
uint256[] memory matchIds = (sp.offerId > 0)
? sp.ids
: LiquidityLib.findMatchInWantIds(sp.ids, s2.intIdx, liq.wantOrIds, liq.wantAndIds);
require(matchIds.length > 0, "OC: NO_ID_MATCH");
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
sp.lid,
sp.amount,
0,
s2.nft,
sp.addrs.provider,
msg.sender
)
);
s2.feePurse.unlock(sp.addrs.provider, liq.protoFeePurseId);
s2.feePurse.unlock(sp.addrs.provider, liq.mktCreatorFeePurseId);
liq.protoFeePurseId = 0;
liq.mktCreatorFeePurseId = 0;
s2.feePurse.transferFrom(sp.addrs.provider, mkt.creator, feeInfo.mktCreatorFee);
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, mkt.base.addr), s2.operatorMgr.isOperator(sp.operator));
if (bools.sharable) {
s2.feePurse.transferFrom(sp.addrs.provider, address(this), (feeInfo.protoFee * s1.feeBPs[1]) / 10000);
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
address opAddr = s2.operatorMgr.getOperator(sp.operator);
s2.feePurse.transferFrom(sp.addrs.provider, opAddr, (feeInfo.protoFee * s1.feeBPs[2]) / 10000);
totalFeeBps -= s1.feeBPs[2];
}
s2.feePurse.transferFrom(sp.addrs.provider, s1.inventor, (feeInfo.protoFee * totalFeeBps) / 10000);
for (uint256 i = 0; i < matchIds.length; i++) {
if (matchIds[i] == 0) continue;
if (mkt.quote.isERC721()) IERC721Strip(mkt.quote.addr).transferFrom(sdr, sp.addrs.provider, matchIds[i]);
else IERC1155Strip(mkt.quote.addr).safeTransferFrom(sdr, sp.addrs.provider, matchIds[i], 1, "");
}
for (uint256 i = 0; i < liq.ids.length; i++)
if (mkt.base.isERC721()) IERC721Strip(mkt.base.addr).transferFrom(address(this), sp.addrs.recipient.setOrDef(sdr), liq.ids[i]);
else IERC1155Strip(mkt.base.addr).safeTransferFrom(address(this), sp.addrs.recipient.setOrDef(sdr), liq.ids[i], 1, "");
s2.marketCore.setCounters(sp.addrs.marketId, false, false, true, mkt.numLiquidity - liq.ids.length);
emit Swap(
sp.addrs.marketId,
sp.addrs.provider,
msg.sender,
sp.addrs.recipient,
address(0),
[0, sp.lid, sp.amount, 0, sp.offerId, sp.operator],
false,
liq.ids,
matchIds
);
delete liq.ids;
}
function swapERC20OrNativeForNFT(
StructsLib.State storage s1,
StructsLib.State2 storage s2,
StructsLib.SwapSlot memory sp,
Structs.Market memory mkt,
Structs.Liquidity storage liq
) public {
uint256 price = (sp.offerId > 0) ? sp.maxPrice : liq.price;
FeeInfo memory feeInfo = FeeLib.computeFee(
ComputeFeeParams(
mkt,
liq,
s2.assetReg,
s2.feePurse,
s1.ints.synthSwapFeeBp,
s1.ints.instantNFTSwapFeeBp,
s1.ints.instantSwapFeeBp,
s1.ints.stableSwapFeeBp,
s2.ints.nftDiscountBp,
sp.lid,
sp.amount,
price,
s2.nft,
sp.addrs.provider,
msg.sender
)
);
s1.feeBalance[mkt.creator][mkt.quote.addr] += feeInfo.mktCreatorFee;
BoolSlot memory bools = BoolSlot(AuxLib.isShareable(s2, mkt.quote.addr), s2.operatorMgr.isOperator(sp.operator));
uint256 totalFeeBps = s1.feeBPs[0] + s1.feeBPs[1] + s1.feeBPs[2];
if (bools.sharable) {
s1.shareablesBalance[mkt.quote.addr] += (feeInfo.protoFee * s1.feeBPs[1]) / 10000;
totalFeeBps -= s1.feeBPs[1];
}
if (bools.isOperator) {
s1.operatorsBalance[s2.operatorMgr.getOperator(sp.operator)][mkt.quote.addr] += (feeInfo.protoFee * s1.feeBPs[2]) / 10000;
totalFeeBps -= s1.feeBPs[2];
}
s1.inventorBalance[mkt.quote.addr] += (feeInfo.protoFee * totalFeeBps) / 10000;
if (mkt.quote.isERC20()) {
IERC20(mkt.quote.addr).safeTransferFrom(msg.sender, address(this), price);
IERC20(mkt.quote.addr).safeTransfer(sp.addrs.provider, price - feeInfo.totalFees);
} else if (mkt.quote.isNative()) {
require(msg.value >= price, "OC: LOW_DEPOSIT");
payable(sp.addrs.provider).transfer(price - feeInfo.totalFees);
}
for (uint256 i = 0; i < liq.ids.length; i++)
if (mkt.base.isERC721())
IERC721Strip(mkt.base.addr).transferFrom(address(this), sp.addrs.recipient.setOrDef(msg.sender), liq.ids[i]);
else IERC1155Strip(mkt.base.addr).safeTransferFrom(address(this), sp.addrs.recipient.setOrDef(msg.sender), liq.ids[i], 1, "");
s2.marketCore.setCounters(sp.addrs.marketId, false, false, true, mkt.numLiquidity - liq.ids.length);
emit Swap(
sp.addrs.marketId,
sp.addrs.provider,
msg.sender,
sp.addrs.recipient,
address(0),
[0, sp.lid, sp.amount, price, sp.offerId, sp.operator],
false,
liq.ids,
new uint256[](0)
);
delete liq.ids;
}
}
文件 44 的 44:WithdrawLib.sol
pragma solidity ^0.8.13;
import "./StructsLib.sol";
import "../token/interfaces/IERC20.sol";
import "../common/SafeERC20.sol";
import "../pools/interfaces/IFeePool.sol";
import "../feepurse/interfaces/IFeePurse.sol";
import "../market/interfaces/IMarketCore.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
library WithdrawLib {
using SafeERC20 for IERC20;
event TransferredToFeePool(address indexed token, uint256 amount, address convAsset, uint256 convAmount);
event TransferInventorBalance(address owner, address token, uint256 amount);
event TransferOperatorBalance(address owner, address token, uint256 amount);
function withdrawInventorBalance(StructsLib.State storage state, StructsLib.State2 storage state2, address asset) public {
uint256 bal = state.inventorBalance[asset];
state.inventorBalance[asset] = 0;
if (IMarketCore(state2.marketCore).getNativeAssetAddr() == asset) {
payable(state.inventor).transfer(bal);
} else {
IERC20(asset).transfer(state.inventor, bal);
}
emit TransferInventorBalance(state.inventor, asset, bal);
bal = state2.feePurse.balanceOf(state.inventor);
if (bal > 0) {
state2.feePurse.withdrawFrom(bal, state.inventor, state.inventor);
emit TransferInventorBalance(state.inventor, asset, bal);
}
}
function withdrawOperatorBalance(StructsLib.State storage state, StructsLib.State2 storage state2, address token) public {
uint256 bal = state.operatorsBalance[msg.sender][token];
state.operatorsBalance[msg.sender][token] = 0;
if (IMarketCore(state2.marketCore).getNativeAssetAddr() == token) {
payable(msg.sender).transfer(bal);
} else {
IERC20(token).transfer(msg.sender, bal);
}
emit TransferOperatorBalance(msg.sender, token, bal);
bal = state2.feePurse.balanceOf(msg.sender);
if (bal > 0) {
state2.feePurse.withdrawFrom(bal, msg.sender, msg.sender);
emit TransferOperatorBalance(msg.sender, token, bal);
}
}
function transferToFeePool(StructsLib.State storage state, StructsLib.State2 storage state2, address token) public {
uint256 lastTx = state.lastFeePoolTransfer[token];
require(lastTx == 0 || block.timestamp - lastTx > state.feePoolTxInterval, "OC: NOT_READY");
uint256 bal = state.shareablesBalance[token];
if (bal > 0) {
state.shareablesBalance[token] = 0;
state.lastFeePoolTransfer[token] = block.timestamp;
ISwapRouter swapRouter = ISwapRouter(state.ammSwapRouter);
address tokenOut = state2.ammEth;
uint256 poolFee = state2.ints.ammEthPoolFee;
if (state2.ammSwapPool[token].outAddr != address(0)) {
tokenOut = state2.ammSwapPool[token].outAddr;
poolFee = state2.ammSwapPool[token].poolFee;
}
require(token != tokenOut, "OC: SAME_ASSET");
IERC20(token).safeIncreaseAllowance(address(swapRouter), bal);
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: token,
tokenOut: tokenOut,
fee: uint24(poolFee),
recipient: address(state2.feePool),
deadline: block.timestamp,
amountIn: bal,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
uint256 amountOut;
if (token == IMarketCore(state2.marketCore).getNativeAssetAddr()) {
amountOut = swapRouter.exactInputSingle{value: bal}(params);
} else {
amountOut = swapRouter.exactInputSingle(params);
}
state2.feePool.notifyFeeDeposit(tokenOut, amountOut);
emit TransferredToFeePool(token, bal, tokenOut, amountOut);
}
bal = state2.feePurse.balanceOf(address(this));
if (bal > 0) {
state2.feePurse.withdraw(bal, address(state2.feePool));
state2.feePool.notifyFeeDeposit(address(state2.feePurse.getFeeToken()), bal);
emit TransferredToFeePool(address(state2.feePurse.getFeeToken()), bal, address(0), 0);
}
}
}
{
"compilationTarget": {
"contracts/core/Core.sol": "Core"
},
"evmVersion": "london",
"libraries": {
"contracts/core/AuxLib.sol:AuxLib": "0xe9914155cbbbd33c9db88a7134ff4aac74162a28",
"contracts/core/FeeLib.sol:FeeLib": "0x6626dc82f9614401bfe4093bffbadf781322e203",
"contracts/core/FungibleLiquidityLib.sol:FungibleLiquidityLib": "0xb6079afb68b4efdb30bf35aee2335ea80a191d9a",
"contracts/core/LiquidityLib.sol:LiquidityLib": "0x85a2eef7b8cfcb6c05b9991a6063d61f1b66f122",
"contracts/core/NonFungibleLiquidityLib.sol:NonFungibleLiquidityLib": "0x4f30ea55ada00a9ea2434962794b347f62281487",
"contracts/core/OfferLib.sol:OfferLib": "0x4e911c672c6744d37b462b2a8534e6ed4253ac0c",
"contracts/core/SwapLib.sol:SwapLib": "0xeb4edc8d6efe86bf39b7f493abddbd2aa9b3c236",
"contracts/core/WithdrawLib.sol:WithdrawLib": "0x7a22af56d43a9cc78d4cbe3ae1c764377de73a9a"
},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_marketCore","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_minTimeToPay","type":"uint256"},{"internalType":"uint256","name":"_orderGraceDur","type":"uint256"},{"internalType":"uint256","name":"_maxOpenOrders","type":"uint256"},{"internalType":"uint256","name":"_maxOpenDisputes","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"address","name":"finalizer","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"action","type":"uint256"}],"name":"FinalizedByManagerSig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"bp","type":"uint256"}],"name":"NFTDiscountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"marketId","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"lid","type":"uint256"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"},{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"expireDuration","type":"uint256"}],"name":"NewOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"acceptor","type":"address"},{"indexed":false,"internalType":"uint256","name":"executeAt","type":"uint256"}],"name":"OfferAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"canceller","type":"address"}],"name":"OfferCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"executor","type":"address"}],"name":"OfferExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"unacceptor","type":"address"}],"name":"OfferUnaccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":true,"internalType":"address","name":"offerer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"execDelayDur","type":"uint256"}],"name":"OfferUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderID","type":"uint256"},{"indexed":true,"internalType":"address","name":"canceller","type":"address"},{"indexed":true,"internalType":"bool","name":"byDispute","type":"bool"}],"name":"OrderCancelled","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":false,"internalType":"uint256","name":"inventor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shared","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"operator","type":"uint256"}],"name":"ProtocolFeeSplitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"instantSwapFeeBp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"synthSwapFeeBp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableSwapFeeBp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fixedSynthSwapFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fixedNFTSwapFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"instantNFTSwapFeeBp","type":"uint256"}],"name":"ProtocolFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mid","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"releaser","type":"address"},{"indexed":false,"internalType":"uint256[6]","name":"numTypeInfo","type":"uint256[6]"},{"indexed":false,"internalType":"bool","name":"byDispute","type":"bool"},{"indexed":false,"internalType":"uint256[]","name":"idsFromProvider","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"idsFromTaker","type":"uint256[]"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mid","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256[7]","name":"numTypeInfo","type":"uint256[7]"},{"indexed":false,"internalType":"uint256[]","name":"idsFromProvider","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"idsFromTaker","type":"uint256[]"}],"name":"SwapOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderID","type":"uint256"},{"indexed":false,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"uint256","name":"disputeDelayDur","type":"uint256"}],"name":"SwapOrderPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"marketId","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"lid","type":"uint256"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"TogglePause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferInventorBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferOperatorBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"convAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"convAmount","type":"uint256"}],"name":"TransferredToFeePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapRouter","type":"address"},{"indexed":false,"internalType":"address","name":"ethErc20Addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"poolFee","type":"uint256"}],"name":"UpdatedAMMInfo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"input","type":"address"},{"indexed":false,"internalType":"address","name":"output","type":"address"},{"indexed":false,"internalType":"uint256","name":"poolFee","type":"uint256"}],"name":"UpdatedAMMPoolInfo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedAssetRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedBadge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedDisputeManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedFeePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interval","type":"uint256"}],"name":"UpdatedFeePoolConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedFeePurse","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"marketId","type":"address"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"deduct","type":"bool"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"},{"indexed":false,"internalType":"uint256","name":"liq","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"wantOrIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"wantAndIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"minSwap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxSwap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeToPay","type":"uint256"}],"name":"UpdatedFungibleLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedInventor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"marketId","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"address","name":"oldManager","type":"address"}],"name":"UpdatedLiquidityManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"market","type":"address"},{"indexed":false,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"liq","type":"uint256"},{"indexed":false,"internalType":"string[2][]","name":"badges","type":"string[2][]"}],"name":"UpdatedLiquiditySwapBadges","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedMarketCore","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"UpdatedMaxOpenDisputes","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"UpdatedMaxOpenOrders","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"UpdatedMinTimeToPay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedMinerRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"marketId","type":"address"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"deduct","type":"bool"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"},{"indexed":false,"internalType":"uint256","name":"lid","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"wantOrIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"wantAndIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"timeToPay","type":"uint256"}],"name":"UpdatedNonFungibleLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"UpdatedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"UpdatedOrderGraceDur","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"marketId","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"uint256","name":"lid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"UpdatedPrice","type":"event"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"},{"internalType":"uint256","name":"delay","type":"uint256"}],"name":"acceptOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"addr","type":"address"}],"name":"canCreateDispute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"cancelOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelOrderByDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"expireAt","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"cancelOrderByManagerSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mid","type":"address"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"orderAmt","type":"uint256"},{"internalType":"uint256","name":"orderPrice","type":"uint256"}],"name":"computeSwapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"interval","type":"uint256"}],"name":"configureFeePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"operator","type":"uint256"}],"name":"createOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"},{"internalType":"uint256","name":"txDeadline","type":"uint256"}],"name":"executeOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_asset","type":"address"}],"name":"feeBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeBPs","outputs":[{"internalType":"uint256[3]","name":"","type":"uint256[3]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_mid","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_lid","type":"uint256"}],"name":"getLiquidity","outputs":[{"components":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"minSwap","type":"uint256"},{"internalType":"uint256","name":"maxSwap","type":"uint256"},{"internalType":"uint256","name":"timeToPay","type":"uint256"},{"internalType":"uint256","name":"openOrders","type":"uint256"},{"internalType":"uint256","name":"openDisputes","type":"uint256"},{"internalType":"uint256","name":"protoFeePurseId","type":"uint256"},{"internalType":"uint256","name":"mktCreatorFeePurseId","type":"uint256"},{"internalType":"uint256","name":"protoFeeRate","type":"uint256"},{"internalType":"uint256","name":"mktCreatorFeeRate","type":"uint256"},{"internalType":"uint256[]","name":"wantOrIds","type":"uint256[]"},{"internalType":"uint256[]","name":"wantAndIds","type":"uint256[]"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"address","name":"target","type":"address"}],"internalType":"struct Structs.Liquidity","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"provider","type":"address"}],"name":"getLiquidityManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"id","type":"address"}],"name":"getMarket","outputs":[{"components":[{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"numOrders","type":"uint256"},{"internalType":"uint256","name":"numDisputes","type":"uint256"},{"internalType":"uint256","name":"numLiquidity","type":"uint256"},{"internalType":"uint256","name":"commission","type":"uint256"},{"internalType":"uint256","name":"poolId","type":"uint256"},{"components":[{"internalType":"uint256","name":"disputeDelayDur","type":"uint256"}],"internalType":"struct Structs.MarketDur","name":"dur","type":"tuple"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"enum Structs.AssetType","name":"assetType","type":"uint8"}],"internalType":"struct Structs.Asset","name":"base","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"enum Structs.AssetType","name":"assetType","type":"uint8"}],"internalType":"struct Structs.Asset","name":"quote","type":"tuple"},{"components":[{"internalType":"bool","name":"put","type":"bool"},{"internalType":"bool","name":"swap","type":"bool"},{"internalType":"bool","name":"offerOnly","type":"bool"},{"internalType":"bool","name":"allowZeroOfferPrice","type":"bool"}],"internalType":"struct Structs.MarketPerms","name":"perms","type":"tuple"}],"internalType":"struct Structs.Market","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getOffer","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"liq","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"execAt","type":"uint256"},{"internalType":"uint256","name":"operator","type":"uint256"},{"internalType":"bool","name":"accepted","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"},{"internalType":"bool","name":"executed","type":"bool"}],"internalType":"struct Structs.Offer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getOrder","outputs":[{"components":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"finalizer","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"payDeadline","type":"uint256"},{"internalType":"uint256","name":"cancelAt","type":"uint256"},{"internalType":"uint256","name":"disputeFrom","type":"uint256"},{"internalType":"uint256","name":"offerId","type":"uint256"},{"internalType":"uint256","name":"operator","type":"uint256"},{"internalType":"uint256[]","name":"takerIds","type":"uint256[]"},{"internalType":"uint256[]","name":"providerIds","type":"uint256[]"},{"internalType":"bool","name":"paid","type":"bool"},{"internalType":"bool","name":"released","type":"bool"},{"internalType":"bool","name":"disputed","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"}],"internalType":"struct Structs.Order","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"address","name":"addr","type":"address"}],"name":"getReqSwapBadges","outputs":[{"internalType":"string[2][]","name":"","type":"string[2][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_mid","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_lid","type":"uint256"}],"name":"hasLiquidity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"hasOrder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"inventorBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isVerified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"markAsDisputed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"markOrderAsPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"expireAt","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"markOrderAsPaidByManagerSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"asset","type":"address"}],"name":"operatorBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"releaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"releaseOrderByDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"expireAt","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"releaseOrderByManagerSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"address","name":"ethErc20Addr","type":"address"},{"internalType":"uint256","name":"poolFee","type":"uint256"}],"name":"setAmmInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"input","type":"address"},{"internalType":"address","name":"out","type":"address"},{"internalType":"uint256","name":"poolFee","type":"uint256"}],"name":"setAmmPoolInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setAssetRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"val","type":"address"}],"name":"setBadgeMgr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bp","type":"uint256"}],"name":"setDiscountForNFTHolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setDisputeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setFeePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"val","type":"address"}],"name":"setFeePurse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setInventor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"manager","type":"address"}],"name":"setLiquidityManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setMarketCore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setMaxOpenDisputes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setMaxOpenOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setMinTimeToPay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setMinerRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setOrderGraceDur","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_instantSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"_synthSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"_stableSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"_fixedSynthSwapFee","type":"uint256"},{"internalType":"uint256","name":"_fixedNFTSwapFee","type":"uint256"},{"internalType":"uint256","name":"_instantNFTSwapFeeBp","type":"uint256"}],"name":"setProtoFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"inventorBP","type":"uint256"},{"internalType":"uint256","name":"sharedBP","type":"uint256"},{"internalType":"uint256","name":"operatorBP","type":"uint256"}],"name":"setProtoFeeSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"string[2][]","name":"badgeIds","type":"string[2][]"}],"name":"setSwapBadgeForLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"shareablesBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"components":[{"internalType":"uint256","name":"instantSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"synthSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"stableSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"instantNFTSwapFeeBp","type":"uint256"},{"internalType":"uint256","name":"fixedSynthSwapFee","type":"uint256"},{"internalType":"uint256","name":"fixedNFTSwapFee","type":"uint256"},{"internalType":"uint256","name":"maxOpenOrders","type":"uint256"},{"internalType":"uint256","name":"maxOpenDisputes","type":"uint256"}],"internalType":"struct StructsLib.IntSlotState","name":"ints","type":"tuple"},{"internalType":"uint256","name":"minTimeToPay","type":"uint256"},{"internalType":"uint256","name":"orderGraceDur","type":"uint256"},{"internalType":"uint256","name":"numOrders","type":"uint256"},{"internalType":"uint256","name":"feePoolTxInterval","type":"uint256"},{"internalType":"address","name":"inventor","type":"address"},{"internalType":"address","name":"ammSwapRouter","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state2","outputs":[{"components":[{"internalType":"uint256","name":"nftDiscountBp","type":"uint256"},{"internalType":"uint256","name":"ammEthPoolFee","type":"uint256"}],"internalType":"struct StructsLib.UintSlotState2","name":"ints","type":"tuple"},{"internalType":"address","name":"disputeManager","type":"address"},{"internalType":"address","name":"nft","type":"address"},{"internalType":"address","name":"ammEth","type":"address"},{"internalType":"contract IAssetRegistry","name":"assetReg","type":"address"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"contract IMarketCore","name":"marketCore","type":"address"},{"internalType":"contract IFeePool","name":"feePool","type":"address"},{"internalType":"contract IFeePurse","name":"feePurse","type":"address"},{"internalType":"contract IBadge","name":"badge","type":"address"},{"internalType":"contract IOperator","name":"operatorMgr","type":"address"},{"internalType":"contract IMinerRegistry","name":"minerReg","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"txDeadline","type":"uint256"},{"internalType":"uint256","name":"operator","type":"uint256"}],"name":"swapQuoteForBase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"uint256","name":"expireAt","type":"uint256"}],"name":"togglePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"transferToFeePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"unacceptOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"bool","name":"deduct","type":"bool"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256[2]","name":"amountAndPrice","type":"uint256[2]"},{"internalType":"uint256[]","name":"wantOrIds","type":"uint256[]"},{"internalType":"uint256[]","name":"wantAndIds","type":"uint256[]"},{"internalType":"uint256[5]","name":"limits","type":"uint256[5]"}],"name":"updateFungibleLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_marketId","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_lid","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_expireAt","type":"uint256"}],"name":"updateLiquidityPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"bool","name":"deduct","type":"bool"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256[]","name":"wantOrIds","type":"uint256[]"},{"internalType":"uint256[]","name":"wantAndIds","type":"uint256[]"},{"internalType":"uint256[3]","name":"limits","type":"uint256[3]"}],"name":"updateNonFungibleLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"updateOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketId","type":"address"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"uint256","name":"lid","type":"uint256"},{"internalType":"bool","name":"incr","type":"bool"}],"name":"updateOpenDisputesCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"withdrawFeeBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"withdrawInventorBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawOperatorBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]