编译器
0.8.25+commit.b61c2a91
文件 1 的 36:Address.sol
pragma solidity ^0.8.20;
library Address {
error AddressInsufficientBalance(address account);
error AddressEmptyCode(address target);
error FailedInnerCall();
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
文件 2 的 36:ConsiderationLib.sol
pragma solidity ^0.8.24;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IEscrow} from "./Escrow.sol";
import {Parties, PayableParties, InsufficientBalance} from "./TypesAndConstants.sol";
struct Disbursement {
address to;
uint256 amount;
}
struct Consideration {
Disbursement[] thirdParty;
uint256 maxPlatformFee;
uint256 total;
}
struct ERC20Consideration {
Disbursement[] thirdParty;
uint256 maxPlatformFee;
uint256 total;
IERC20 currency;
}
library ConsiderationLib {
using Address for address payable;
using SafeERC20 for IERC20;
function _disburse(Consideration memory c, PayableParties memory parties, address payable feeRecipient, uint256 fee)
internal
{
if (address(this).balance < c.total) {
revert InsufficientBalance(address(this).balance, c.total);
}
feeRecipient.sendValue(fee);
Disbursement[] memory tP = c.thirdParty;
for (uint256 i = 0; i < tP.length; ++i) {
payable(tP[i].to).sendValue(tP[i].amount);
}
parties.seller.sendValue(address(this).balance);
}
function _cancel(Consideration memory, PayableParties memory parties, IEscrow escrow) internal {
uint256 bal = address(this).balance;
if (bal > 0) {
escrow.deposit{value: bal}(parties.buyer);
}
}
function _postExecutionInvariantsMet(Consideration memory, PayableParties memory) internal view returns (bool) {
return address(this).balance == 0;
}
function _disburse(ERC20Consideration memory c, Parties memory parties, address feeRecipient, uint256 fee)
internal
{
uint256 remaining = c.total;
c.currency.safeTransferFrom(parties.buyer, feeRecipient, fee);
remaining -= fee;
Disbursement[] memory tP = c.thirdParty;
for (uint256 i = 0; i < tP.length; ++i) {
c.currency.safeTransferFrom(parties.buyer, tP[i].to, tP[i].amount);
remaining -= tP[i].amount;
}
c.currency.safeTransferFrom(parties.buyer, parties.seller, remaining);
}
function _cancel(ERC20Consideration memory, Parties memory, IEscrow) internal pure {}
function _postExecutionInvariantsMet(ERC20Consideration memory, Parties memory) internal pure returns (bool) {
return true;
}
}
文件 3 的 36:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 4 的 36:Create2.sol
pragma solidity ^0.8.20;
library Create2 {
error Create2InsufficientBalance(uint256 balance, uint256 needed);
error Create2EmptyBytecode();
error Create2FailedDeployment();
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Create2InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
if (addr == address(0)) {
revert Create2FailedDeployment();
}
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer)
let start := add(ptr, 0x0b)
mstore8(start, 0xff)
addr := keccak256(start, 85)
}
}
}
文件 5 的 36:ERC721ForERC20Swap.sol
pragma solidity 0.8.25;
import {ERC20Consideration} from "../ConsiderationLib.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {Parties} from "../TypesAndConstants.sol";
struct ERC721ForERC20Swap {
Parties parties;
ERC721TransferLib.ERC721Token offer;
ERC20Consideration consideration;
uint256 validUntilTime;
}
文件 6 的 36:ERC721ForERC20Swapper.gen.sol
pragma solidity 0.8.25;
import {ERC721ForERC20Swap} from "./ERC721ForERC20Swap.sol";
import {ERC721ForERC20SwapperBase} from "./ERC721ForERC20SwapperBase.gen.sol";
contract ERC721ForERC20Swapper is ERC721ForERC20SwapperBase {
constructor(ERC721ForERC20Swap memory swap, uint256 currentChainId)
ERC721ForERC20SwapperBase(swap, currentChainId)
{}
}
文件 7 的 36:ERC721ForERC20SwapperBase.gen.sol
pragma solidity 0.8.25;
import {ERC721ForERC20Swap} from "./ERC721ForERC20Swap.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {IETHome, Message} from "../ET.sol";
import {ConsiderationLib} from "../ConsiderationLib.sol";
import {SwapperBase} from "../SwapperBase.sol";
import {
Action,
ActionMessageLib,
UnsupportedAction,
FILL,
CANCEL,
FILLED_ARTIFACT,
CANCELLED_ARTIFACT,
ExcessPlatformFee,
SwapExpired,
currentChainId
} from "../TypesAndConstants.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
contract ERC721ForERC20SwapperBase is SwapperBase {
using ActionMessageLib for Message;
using ConsiderationLib for *;
constructor(ERC721ForERC20Swap memory swap, uint256 currentChainId_) {
assert(currentChainId() == currentChainId_);
Message message = IETHome(msg.sender).etMessage();
Action action = message.action();
bytes3 codeToDeploy;
if (action == FILL) {
uint256 validUntil = swap.validUntilTime;
if (validUntil != 0 && block.timestamp > swap.validUntilTime) {
revert SwapExpired(swap.validUntilTime);
}
codeToDeploy = FILLED_ARTIFACT;
ERC721TransferLib._transfer(swap.offer, _asNonPayableParties(swap.parties));
(address payable feeRecipient, uint16 basisPoints) = message.feeConfig();
uint256 fee = Math.mulDiv(swap.consideration.total, basisPoints, 10_000);
if (fee > swap.consideration.maxPlatformFee) {
revert ExcessPlatformFee(fee, swap.consideration.maxPlatformFee);
}
swap.consideration._disburse(swap.parties, feeRecipient, fee);
} else if (action == CANCEL) {
codeToDeploy = CANCELLED_ARTIFACT;
swap.consideration._cancel(swap.parties, message.escrow());
} else {
revert UnsupportedAction(action);
}
assert(swap.consideration._postExecutionInvariantsMet(swap.parties));
assembly ("memory-safe") {
mstore(0, codeToDeploy)
return(0, 3)
}
}
}
文件 8 的 36:ERC721ForERC20SwapperDeployer.gen.sol
pragma solidity 0.8.25;
import {ERC721ForERC20Swap} from "./ERC721ForERC20Swap.sol";
import {ERC721ForERC20Swapper} from "./ERC721ForERC20Swapper.gen.sol";
import {ETDeployer, ETPredictor} from "../ET.sol";
import {SwapperDeployerBase} from "../SwapperDeployerBase.sol";
import {SwapperProposerBase} from "../SwapperProposerBase.sol";
import {OnlyPartyCanCancel, ActionMessageLib, CANCEL_MSG, ISwapperEvents} from "../TypesAndConstants.sol";
contract ERC721ForERC20SwapperPredictor {
function _swapper(ERC721ForERC20Swap calldata swap, bytes32 salt, address deployer, uint256 chainId)
internal
pure
returns (address)
{
return ETPredictor.deploymentAddress(_bytecode(swap, chainId), salt, deployer);
}
function _bytecode(ERC721ForERC20Swap calldata swap, uint256 chainId) internal pure returns (bytes memory) {
return abi.encodePacked(type(ERC721ForERC20Swapper).creationCode, abi.encode(swap, chainId));
}
}
abstract contract ERC721ForERC20SwapperDeployer is
ERC721ForERC20SwapperPredictor,
ETDeployer,
SwapperDeployerBase,
ISwapperEvents
{
function fillERC721ForERC20(ERC721ForERC20Swap calldata swap, bytes32 salt) external payable returns (address) {
(address payable feeRecipient, uint16 basisPoints) = _platformFeeConfig();
address a = _deploy(
_bytecode(swap, _currentChainId()),
msg.value,
salt,
ActionMessageLib.fillWithFeeConfig(feeRecipient, basisPoints)
);
emit Filled(a);
return a;
}
function cancelERC721ForERC20(ERC721ForERC20Swap calldata swap, bytes32 salt) external returns (address) {
if (msg.sender != swap.parties.seller && msg.sender != swap.parties.buyer) {
revert OnlyPartyCanCancel();
}
address a = _deploy(_bytecode(swap, _currentChainId()), 0, salt, ActionMessageLib.cancelWithEscrow(_escrow()));
emit Cancelled(a);
return a;
}
function swapperOfERC721ForERC20(ERC721ForERC20Swap calldata swap, bytes32 salt) external view returns (address) {
return _swapper(swap, salt, address(this), _currentChainId());
}
}
interface IERC721ForERC20SwapperProposerEvents {
event ERC721ForERC20Proposal(
address indexed swapper, address indexed seller, address indexed buyer, ERC721ForERC20Swap, bytes32 salt
);
}
abstract contract ERC721ForERC20SwapperProposer is
ERC721ForERC20SwapperPredictor,
IERC721ForERC20SwapperProposerEvents,
SwapperProposerBase
{
function proposeERC721ForERC20(ERC721ForERC20Swap calldata swap) external returns (bytes32, address) {
bytes32 salt = blockhash(block.number - 1);
(address deployer, uint256 chainId) = _swapperDeployer();
address swapper_ = _swapper(swap, salt, deployer, chainId);
emit ERC721ForERC20Proposal(swapper_, swap.parties.seller, swap.parties.buyer, swap, salt);
return (salt, swapper_);
}
function _swapperDeployer(ERC721ForERC20Swap calldata) internal virtual returns (address, uint256 chainId) {
return _swapperDeployer();
}
}
function _enforceERC721ForERC20SwapperCtorSig() {
assert(false);
ERC721ForERC20Swap memory s;
new ERC721ForERC20Swapper(s, uint256(0));
}
文件 9 的 36:ERC721ForNativeSwap.sol
pragma solidity 0.8.25;
import {Consideration} from "../ConsiderationLib.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {PayableParties} from "../TypesAndConstants.sol";
struct ERC721ForNativeSwap {
PayableParties parties;
ERC721TransferLib.ERC721Token offer;
Consideration consideration;
uint256 validUntilTime;
}
文件 10 的 36:ERC721ForNativeSwapper.gen.sol
pragma solidity 0.8.25;
import {ERC721ForNativeSwap} from "./ERC721ForNativeSwap.sol";
import {ERC721ForNativeSwapperBase} from "./ERC721ForNativeSwapperBase.gen.sol";
contract ERC721ForNativeSwapper is ERC721ForNativeSwapperBase {
constructor(ERC721ForNativeSwap memory swap, uint256 currentChainId)
payable
ERC721ForNativeSwapperBase(swap, currentChainId)
{}
}
文件 11 的 36:ERC721ForNativeSwapperBase.gen.sol
pragma solidity 0.8.25;
import {ERC721ForNativeSwap} from "./ERC721ForNativeSwap.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {IETHome, Message} from "../ET.sol";
import {ConsiderationLib} from "../ConsiderationLib.sol";
import {SwapperBase} from "../SwapperBase.sol";
import {
Action,
ActionMessageLib,
UnsupportedAction,
FILL,
CANCEL,
FILLED_ARTIFACT,
CANCELLED_ARTIFACT,
ExcessPlatformFee,
SwapExpired,
currentChainId
} from "../TypesAndConstants.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
contract ERC721ForNativeSwapperBase is SwapperBase {
using ActionMessageLib for Message;
using ConsiderationLib for *;
constructor(ERC721ForNativeSwap memory swap, uint256 currentChainId_) {
assert(currentChainId() == currentChainId_);
Message message = IETHome(msg.sender).etMessage();
Action action = message.action();
bytes3 codeToDeploy;
if (action == FILL) {
uint256 validUntil = swap.validUntilTime;
if (validUntil != 0 && block.timestamp > swap.validUntilTime) {
revert SwapExpired(swap.validUntilTime);
}
codeToDeploy = FILLED_ARTIFACT;
ERC721TransferLib._transfer(swap.offer, _asNonPayableParties(swap.parties));
(address payable feeRecipient, uint16 basisPoints) = message.feeConfig();
uint256 fee = Math.mulDiv(swap.consideration.total, basisPoints, 10_000);
if (fee > swap.consideration.maxPlatformFee) {
revert ExcessPlatformFee(fee, swap.consideration.maxPlatformFee);
}
swap.consideration._disburse(swap.parties, feeRecipient, fee);
} else if (action == CANCEL) {
codeToDeploy = CANCELLED_ARTIFACT;
swap.consideration._cancel(swap.parties, message.escrow());
} else {
revert UnsupportedAction(action);
}
assert(swap.consideration._postExecutionInvariantsMet(swap.parties));
assembly ("memory-safe") {
mstore(0, codeToDeploy)
return(0, 3)
}
}
}
文件 12 的 36:ERC721ForNativeSwapperDeployer.gen.sol
pragma solidity 0.8.25;
import {ERC721ForNativeSwap} from "./ERC721ForNativeSwap.sol";
import {ERC721ForNativeSwapper} from "./ERC721ForNativeSwapper.gen.sol";
import {ETDeployer, ETPredictor} from "../ET.sol";
import {SwapperDeployerBase} from "../SwapperDeployerBase.sol";
import {SwapperProposerBase} from "../SwapperProposerBase.sol";
import {OnlyPartyCanCancel, ActionMessageLib, CANCEL_MSG, ISwapperEvents} from "../TypesAndConstants.sol";
contract ERC721ForNativeSwapperPredictor {
function _swapper(ERC721ForNativeSwap calldata swap, bytes32 salt, address deployer, uint256 chainId)
internal
pure
returns (address)
{
return ETPredictor.deploymentAddress(_bytecode(swap, chainId), salt, deployer);
}
function _bytecode(ERC721ForNativeSwap calldata swap, uint256 chainId) internal pure returns (bytes memory) {
return abi.encodePacked(type(ERC721ForNativeSwapper).creationCode, abi.encode(swap, chainId));
}
}
abstract contract ERC721ForNativeSwapperDeployer is
ERC721ForNativeSwapperPredictor,
ETDeployer,
SwapperDeployerBase,
ISwapperEvents
{
function fillERC721ForNative(ERC721ForNativeSwap calldata swap, bytes32 salt) external payable returns (address) {
(address payable feeRecipient, uint16 basisPoints) = _platformFeeConfig();
address a = _deploy(
_bytecode(swap, _currentChainId()),
msg.value,
salt,
ActionMessageLib.fillWithFeeConfig(feeRecipient, basisPoints)
);
emit Filled(a);
return a;
}
function cancelERC721ForNative(ERC721ForNativeSwap calldata swap, bytes32 salt) external returns (address) {
if (msg.sender != swap.parties.seller && msg.sender != swap.parties.buyer) {
revert OnlyPartyCanCancel();
}
address a = _deploy(_bytecode(swap, _currentChainId()), 0, salt, ActionMessageLib.cancelWithEscrow(_escrow()));
emit Cancelled(a);
return a;
}
function swapperOfERC721ForNative(ERC721ForNativeSwap calldata swap, bytes32 salt)
external
view
returns (address)
{
return _swapper(swap, salt, address(this), _currentChainId());
}
}
interface IERC721ForNativeSwapperProposerEvents {
event ERC721ForNativeProposal(
address indexed swapper, address indexed seller, address indexed buyer, ERC721ForNativeSwap, bytes32 salt
);
}
abstract contract ERC721ForNativeSwapperProposer is
ERC721ForNativeSwapperPredictor,
IERC721ForNativeSwapperProposerEvents,
SwapperProposerBase
{
function proposeERC721ForNative(ERC721ForNativeSwap calldata swap) external returns (bytes32, address) {
bytes32 salt = blockhash(block.number - 1);
(address deployer, uint256 chainId) = _swapperDeployer();
address swapper_ = _swapper(swap, salt, deployer, chainId);
emit ERC721ForNativeProposal(swapper_, swap.parties.seller, swap.parties.buyer, swap, salt);
return (salt, swapper_);
}
function _swapperDeployer(ERC721ForNativeSwap calldata) internal virtual returns (address, uint256 chainId) {
return _swapperDeployer();
}
}
function _enforceERC721ForNativeSwapperCtorSig() {
assert(false);
ERC721ForNativeSwap memory s;
new ERC721ForNativeSwapper(s, uint256(0));
}
文件 13 的 36:ERC721TransferLib.sol
pragma solidity ^0.8.24;
import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol";
import {Parties} from "./TypesAndConstants.sol";
library ERC721TransferLib {
error NoCodeAtAddress(address);
struct ERC721Token {
IERC721 addr;
uint256 id;
}
function _transfer(ERC721Token memory token, Parties memory parties) internal {
token.addr.transferFrom(parties.seller, parties.buyer, token.id);
}
function _safeTransfer(ERC721Token memory token, Parties memory parties, bytes memory data) internal {
token.addr.safeTransferFrom(parties.seller, parties.buyer, token.id, data);
}
struct MultiERC721Token {
IERC721 addr;
uint256[] ids;
}
function _transfer(MultiERC721Token memory tokens, Parties memory parties) internal {
_transfer(tokens, _reusableTransferCallData(parties));
}
function _safeTransfer(MultiERC721Token memory tokens, Parties memory parties, bytes memory data) internal {
_transfer(tokens, _reusableSafeTransferCallData(parties, data));
}
function _transfer(MultiERC721Token[] memory tokens, Parties memory parties) internal {
bytes memory callData = _reusableTransferCallData(parties);
for (uint256 i = 0; i < tokens.length; ++i) {
_transfer(tokens[i], callData);
}
}
function _safeTransfer(MultiERC721Token[] memory tokens, Parties memory parties, bytes memory data) internal {
bytes memory callData = _reusableSafeTransferCallData(parties, data);
for (uint256 i = 0; i < tokens.length; ++i) {
_transfer(tokens[i], callData);
}
}
function _reusableTransferCallData(Parties memory parties) private pure returns (bytes memory) {
return abi.encodeCall(IERC721.transferFrom, (parties.seller, parties.buyer, 0));
}
function _reusableSafeTransferCallData(Parties memory parties, bytes memory data)
private
pure
returns (bytes memory)
{
return abi.encodeWithSignature(
"safeTransferFrom(address,address,uint256,bytes)", parties.seller, parties.buyer, 0, data
);
}
function _transfer(MultiERC721Token memory token, bytes memory reusableCallData) private {
address addr = address(token.addr);
if (addr.code.length == 0) {
revert NoCodeAtAddress(addr);
}
uint256[] memory ids = token.ids;
assembly ("memory-safe") {
let idSrc := add(ids, 0x20)
let idDst := add(reusableCallData, 0x64)
let dataPtr := add(reusableCallData, 0x20)
for { let end := add(idSrc, mul(mload(ids), 0x20)) } lt(idSrc, end) { idSrc := add(idSrc, 0x20) } {
mcopy(idDst, idSrc, 0x20)
if iszero(call(gas(), addr, 0, dataPtr, reusableCallData, 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
}
文件 14 的 36:ET.sol
pragma solidity ^0.8.24;
import {Create2} from "./Create2.sol";
import {Create2 as OZCreate2} from "@openzeppelin/contracts/utils/Create2.sol";
type Message is bytes32;
contract ET {
function _phoneHome() internal view returns (Message) {
return IETHome(msg.sender).etMessage();
}
}
interface IETHome {
function etMessage() external view returns (Message);
}
library ETPredictor {
function deploymentAddress(bytes memory bytecode, bytes32 salt) internal view returns (address) {
return deploymentAddress(bytecode, salt, address(this));
}
function deploymentAddress(bytes memory bytecode, bytes32 salt, address deployer) internal pure returns (address) {
return OZCreate2.computeAddress(salt, keccak256(bytecode), deployer);
}
}
contract ETDeployer is IETHome {
error PredictedAddressMismatch(address deployed, address predicted);
function _deploy(address predicted, bytes memory bytecode, uint256 value, bytes32 salt, Message message)
internal
returns (address)
{
assembly ("memory-safe") {
tstore(shr(96, shl(96, predicted)), message)
}
address deployed = Create2.deploy(bytecode, value, salt);
if (deployed != predicted) {
revert PredictedAddressMismatch(deployed, predicted);
}
return deployed;
}
function _deploy(bytes memory bytecode, uint256 value, bytes32 salt, Message message) internal returns (address) {
return _deploy(ETPredictor.deploymentAddress(bytecode, salt), bytecode, value, salt, message);
}
function etMessage() external view returns (Message m) {
assembly ("memory-safe") {
m := tload(caller())
}
}
}
function _eq(Message a, Message b) pure returns (bool) {
return Message.unwrap(a) == Message.unwrap(b);
}
using {_eq as ==} for Message global;
function _neq(Message a, Message b) pure returns (bool) {
return !_eq(a, b);
}
using {_neq as !=} for Message global;
文件 15 的 36:Escrow.sol
pragma solidity 0.8.25;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
interface IEscrowEvents {
event Deposit(address, uint256);
event Withdrawal(address, uint256);
}
bytes32 constant ESCROW_MAGIC_NUMBER =
keccak256("Trust me, bro, I'll protect your ETH. But not ERC20s, don't send me ERC20s!");
interface IEscrow {
function deposit(address payable) external payable;
}
contract Escrow is IEscrow, IEscrowEvents {
error ZeroBalance(address);
mapping(address => uint256) public balance;
function deposit(address payable account) external payable {
balance[account] += msg.value;
emit Deposit(account, msg.value);
}
function withdraw() external {
withdraw(payable(msg.sender));
}
function withdraw(address account) public {
uint256 bal = balance[account];
if (bal == 0) {
revert ZeroBalance(account);
}
balance[account] = 0;
Address.sendValue(payable(account), bal);
emit Withdrawal(account, bal);
}
function isEscrow() external pure returns (bytes32) {
return ESCROW_MAGIC_NUMBER;
}
}
文件 16 的 36:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 17 的 36:IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 18 的 36:IERC20Permit.sol
pragma solidity ^0.8.20;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 19 的 36:IERC721.sol
pragma solidity ^0.8.20;
import {IERC721} from "../token/ERC721/IERC721.sol";
文件 20 的 36:Math.sol
pragma solidity ^0.8.20;
library Math {
error MathOverflowedMulDiv();
enum Rounding {
Floor,
Ceil,
Trunc,
Expand
}
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
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) {
if (b == 0) {
return a / b;
}
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0 = x * y;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (0 - denominator);
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 (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
文件 21 的 36:MultiERC721ForERC20Swap.sol
pragma solidity 0.8.25;
import {ERC20Consideration} from "../ConsiderationLib.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {Parties} from "../TypesAndConstants.sol";
struct MultiERC721ForERC20Swap {
Parties parties;
ERC721TransferLib.MultiERC721Token[] offer;
ERC20Consideration consideration;
uint256 validUntilTime;
}
文件 22 的 36:MultiERC721ForERC20Swapper.gen.sol
pragma solidity 0.8.25;
import {MultiERC721ForERC20Swap} from "./MultiERC721ForERC20Swap.sol";
import {MultiERC721ForERC20SwapperBase} from "./MultiERC721ForERC20SwapperBase.gen.sol";
contract MultiERC721ForERC20Swapper is MultiERC721ForERC20SwapperBase {
constructor(MultiERC721ForERC20Swap memory swap, uint256 currentChainId)
MultiERC721ForERC20SwapperBase(swap, currentChainId)
{}
}
文件 23 的 36:MultiERC721ForERC20SwapperBase.gen.sol
pragma solidity 0.8.25;
import {MultiERC721ForERC20Swap} from "./MultiERC721ForERC20Swap.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {IETHome, Message} from "../ET.sol";
import {ConsiderationLib} from "../ConsiderationLib.sol";
import {SwapperBase} from "../SwapperBase.sol";
import {
Action,
ActionMessageLib,
UnsupportedAction,
FILL,
CANCEL,
FILLED_ARTIFACT,
CANCELLED_ARTIFACT,
ExcessPlatformFee,
SwapExpired,
currentChainId
} from "../TypesAndConstants.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
contract MultiERC721ForERC20SwapperBase is SwapperBase {
using ActionMessageLib for Message;
using ConsiderationLib for *;
constructor(MultiERC721ForERC20Swap memory swap, uint256 currentChainId_) {
assert(currentChainId() == currentChainId_);
Message message = IETHome(msg.sender).etMessage();
Action action = message.action();
bytes3 codeToDeploy;
if (action == FILL) {
uint256 validUntil = swap.validUntilTime;
if (validUntil != 0 && block.timestamp > swap.validUntilTime) {
revert SwapExpired(swap.validUntilTime);
}
codeToDeploy = FILLED_ARTIFACT;
ERC721TransferLib._transfer(swap.offer, _asNonPayableParties(swap.parties));
(address payable feeRecipient, uint16 basisPoints) = message.feeConfig();
uint256 fee = Math.mulDiv(swap.consideration.total, basisPoints, 10_000);
if (fee > swap.consideration.maxPlatformFee) {
revert ExcessPlatformFee(fee, swap.consideration.maxPlatformFee);
}
swap.consideration._disburse(swap.parties, feeRecipient, fee);
} else if (action == CANCEL) {
codeToDeploy = CANCELLED_ARTIFACT;
swap.consideration._cancel(swap.parties, message.escrow());
} else {
revert UnsupportedAction(action);
}
assert(swap.consideration._postExecutionInvariantsMet(swap.parties));
assembly ("memory-safe") {
mstore(0, codeToDeploy)
return(0, 3)
}
}
}
文件 24 的 36:MultiERC721ForERC20SwapperDeployer.gen.sol
pragma solidity 0.8.25;
import {MultiERC721ForERC20Swap} from "./MultiERC721ForERC20Swap.sol";
import {MultiERC721ForERC20Swapper} from "./MultiERC721ForERC20Swapper.gen.sol";
import {ETDeployer, ETPredictor} from "../ET.sol";
import {SwapperDeployerBase} from "../SwapperDeployerBase.sol";
import {SwapperProposerBase} from "../SwapperProposerBase.sol";
import {OnlyPartyCanCancel, ActionMessageLib, CANCEL_MSG, ISwapperEvents} from "../TypesAndConstants.sol";
contract MultiERC721ForERC20SwapperPredictor {
function _swapper(MultiERC721ForERC20Swap calldata swap, bytes32 salt, address deployer, uint256 chainId)
internal
pure
returns (address)
{
return ETPredictor.deploymentAddress(_bytecode(swap, chainId), salt, deployer);
}
function _bytecode(MultiERC721ForERC20Swap calldata swap, uint256 chainId) internal pure returns (bytes memory) {
return abi.encodePacked(type(MultiERC721ForERC20Swapper).creationCode, abi.encode(swap, chainId));
}
}
abstract contract MultiERC721ForERC20SwapperDeployer is
MultiERC721ForERC20SwapperPredictor,
ETDeployer,
SwapperDeployerBase,
ISwapperEvents
{
function fillMultiERC721ForERC20(MultiERC721ForERC20Swap calldata swap, bytes32 salt)
external
payable
returns (address)
{
(address payable feeRecipient, uint16 basisPoints) = _platformFeeConfig();
address a = _deploy(
_bytecode(swap, _currentChainId()),
msg.value,
salt,
ActionMessageLib.fillWithFeeConfig(feeRecipient, basisPoints)
);
emit Filled(a);
return a;
}
function cancelMultiERC721ForERC20(MultiERC721ForERC20Swap calldata swap, bytes32 salt)
external
returns (address)
{
if (msg.sender != swap.parties.seller && msg.sender != swap.parties.buyer) {
revert OnlyPartyCanCancel();
}
address a = _deploy(_bytecode(swap, _currentChainId()), 0, salt, ActionMessageLib.cancelWithEscrow(_escrow()));
emit Cancelled(a);
return a;
}
function swapperOfMultiERC721ForERC20(MultiERC721ForERC20Swap calldata swap, bytes32 salt)
external
view
returns (address)
{
return _swapper(swap, salt, address(this), _currentChainId());
}
}
interface IMultiERC721ForERC20SwapperProposerEvents {
event MultiERC721ForERC20Proposal(
address indexed swapper, address indexed seller, address indexed buyer, MultiERC721ForERC20Swap, bytes32 salt
);
}
abstract contract MultiERC721ForERC20SwapperProposer is
MultiERC721ForERC20SwapperPredictor,
IMultiERC721ForERC20SwapperProposerEvents,
SwapperProposerBase
{
function proposeMultiERC721ForERC20(MultiERC721ForERC20Swap calldata swap) external returns (bytes32, address) {
bytes32 salt = blockhash(block.number - 1);
(address deployer, uint256 chainId) = _swapperDeployer();
address swapper_ = _swapper(swap, salt, deployer, chainId);
emit MultiERC721ForERC20Proposal(swapper_, swap.parties.seller, swap.parties.buyer, swap, salt);
return (salt, swapper_);
}
function _swapperDeployer(MultiERC721ForERC20Swap calldata) internal virtual returns (address, uint256 chainId) {
return _swapperDeployer();
}
}
function _enforceMultiERC721ForERC20SwapperCtorSig() {
assert(false);
MultiERC721ForERC20Swap memory s;
new MultiERC721ForERC20Swapper(s, uint256(0));
}
文件 25 的 36:MultiERC721ForNativeSwap.sol
pragma solidity 0.8.25;
import {Consideration} from "../ConsiderationLib.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {PayableParties} from "../TypesAndConstants.sol";
struct MultiERC721ForNativeSwap {
PayableParties parties;
ERC721TransferLib.MultiERC721Token[] offer;
Consideration consideration;
uint256 validUntilTime;
}
文件 26 的 36:MultiERC721ForNativeSwapper.gen.sol
pragma solidity 0.8.25;
import {MultiERC721ForNativeSwap} from "./MultiERC721ForNativeSwap.sol";
import {MultiERC721ForNativeSwapperBase} from "./MultiERC721ForNativeSwapperBase.gen.sol";
contract MultiERC721ForNativeSwapper is MultiERC721ForNativeSwapperBase {
constructor(MultiERC721ForNativeSwap memory swap, uint256 currentChainId)
payable
MultiERC721ForNativeSwapperBase(swap, currentChainId)
{}
}
文件 27 的 36:MultiERC721ForNativeSwapperBase.gen.sol
pragma solidity 0.8.25;
import {MultiERC721ForNativeSwap} from "./MultiERC721ForNativeSwap.sol";
import {ERC721TransferLib} from "../ERC721TransferLib.sol";
import {IETHome, Message} from "../ET.sol";
import {ConsiderationLib} from "../ConsiderationLib.sol";
import {SwapperBase} from "../SwapperBase.sol";
import {
Action,
ActionMessageLib,
UnsupportedAction,
FILL,
CANCEL,
FILLED_ARTIFACT,
CANCELLED_ARTIFACT,
ExcessPlatformFee,
SwapExpired,
currentChainId
} from "../TypesAndConstants.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
contract MultiERC721ForNativeSwapperBase is SwapperBase {
using ActionMessageLib for Message;
using ConsiderationLib for *;
constructor(MultiERC721ForNativeSwap memory swap, uint256 currentChainId_) {
assert(currentChainId() == currentChainId_);
Message message = IETHome(msg.sender).etMessage();
Action action = message.action();
bytes3 codeToDeploy;
if (action == FILL) {
uint256 validUntil = swap.validUntilTime;
if (validUntil != 0 && block.timestamp > swap.validUntilTime) {
revert SwapExpired(swap.validUntilTime);
}
codeToDeploy = FILLED_ARTIFACT;
ERC721TransferLib._transfer(swap.offer, _asNonPayableParties(swap.parties));
(address payable feeRecipient, uint16 basisPoints) = message.feeConfig();
uint256 fee = Math.mulDiv(swap.consideration.total, basisPoints, 10_000);
if (fee > swap.consideration.maxPlatformFee) {
revert ExcessPlatformFee(fee, swap.consideration.maxPlatformFee);
}
swap.consideration._disburse(swap.parties, feeRecipient, fee);
} else if (action == CANCEL) {
codeToDeploy = CANCELLED_ARTIFACT;
swap.consideration._cancel(swap.parties, message.escrow());
} else {
revert UnsupportedAction(action);
}
assert(swap.consideration._postExecutionInvariantsMet(swap.parties));
assembly ("memory-safe") {
mstore(0, codeToDeploy)
return(0, 3)
}
}
}
文件 28 的 36:MultiERC721ForNativeSwapperDeployer.gen.sol
pragma solidity 0.8.25;
import {MultiERC721ForNativeSwap} from "./MultiERC721ForNativeSwap.sol";
import {MultiERC721ForNativeSwapper} from "./MultiERC721ForNativeSwapper.gen.sol";
import {ETDeployer, ETPredictor} from "../ET.sol";
import {SwapperDeployerBase} from "../SwapperDeployerBase.sol";
import {SwapperProposerBase} from "../SwapperProposerBase.sol";
import {OnlyPartyCanCancel, ActionMessageLib, CANCEL_MSG, ISwapperEvents} from "../TypesAndConstants.sol";
contract MultiERC721ForNativeSwapperPredictor {
function _swapper(MultiERC721ForNativeSwap calldata swap, bytes32 salt, address deployer, uint256 chainId)
internal
pure
returns (address)
{
return ETPredictor.deploymentAddress(_bytecode(swap, chainId), salt, deployer);
}
function _bytecode(MultiERC721ForNativeSwap calldata swap, uint256 chainId) internal pure returns (bytes memory) {
return abi.encodePacked(type(MultiERC721ForNativeSwapper).creationCode, abi.encode(swap, chainId));
}
}
abstract contract MultiERC721ForNativeSwapperDeployer is
MultiERC721ForNativeSwapperPredictor,
ETDeployer,
SwapperDeployerBase,
ISwapperEvents
{
function fillMultiERC721ForNative(MultiERC721ForNativeSwap calldata swap, bytes32 salt)
external
payable
returns (address)
{
(address payable feeRecipient, uint16 basisPoints) = _platformFeeConfig();
address a = _deploy(
_bytecode(swap, _currentChainId()),
msg.value,
salt,
ActionMessageLib.fillWithFeeConfig(feeRecipient, basisPoints)
);
emit Filled(a);
return a;
}
function cancelMultiERC721ForNative(MultiERC721ForNativeSwap calldata swap, bytes32 salt)
external
returns (address)
{
if (msg.sender != swap.parties.seller && msg.sender != swap.parties.buyer) {
revert OnlyPartyCanCancel();
}
address a = _deploy(_bytecode(swap, _currentChainId()), 0, salt, ActionMessageLib.cancelWithEscrow(_escrow()));
emit Cancelled(a);
return a;
}
function swapperOfMultiERC721ForNative(MultiERC721ForNativeSwap calldata swap, bytes32 salt)
external
view
returns (address)
{
return _swapper(swap, salt, address(this), _currentChainId());
}
}
interface IMultiERC721ForNativeSwapperProposerEvents {
event MultiERC721ForNativeProposal(
address indexed swapper, address indexed seller, address indexed buyer, MultiERC721ForNativeSwap, bytes32 salt
);
}
abstract contract MultiERC721ForNativeSwapperProposer is
MultiERC721ForNativeSwapperPredictor,
IMultiERC721ForNativeSwapperProposerEvents,
SwapperProposerBase
{
function proposeMultiERC721ForNative(MultiERC721ForNativeSwap calldata swap) external returns (bytes32, address) {
bytes32 salt = blockhash(block.number - 1);
(address deployer, uint256 chainId) = _swapperDeployer();
address swapper_ = _swapper(swap, salt, deployer, chainId);
emit MultiERC721ForNativeProposal(swapper_, swap.parties.seller, swap.parties.buyer, swap, salt);
return (salt, swapper_);
}
function _swapperDeployer(MultiERC721ForNativeSwap calldata) internal virtual returns (address, uint256 chainId) {
return _swapperDeployer();
}
}
function _enforceMultiERC721ForNativeSwapperCtorSig() {
assert(false);
MultiERC721ForNativeSwap memory s;
new MultiERC721ForNativeSwapper(s, uint256(0));
}
文件 29 的 36:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 30 的 36:Ownable2Step.sol
pragma solidity ^0.8.20;
import {Ownable} from "./Ownable.sol";
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}
文件 31 的 36:SWAP2.sol
pragma solidity 0.8.25;
import {
ERC721ForNativeSwapperDeployer,
ERC721ForNativeSwapperProposer
} from "./ERC721ForNative/ERC721ForNativeSwapperDeployer.gen.sol";
import {
ERC721ForERC20SwapperDeployer,
ERC721ForERC20SwapperProposer
} from "./ERC721ForERC20/ERC721ForERC20SwapperDeployer.gen.sol";
import {
MultiERC721ForNativeSwapperDeployer,
MultiERC721ForNativeSwapperProposer
} from "./MultiERC721ForNative/MultiERC721ForNativeSwapperDeployer.gen.sol";
import {
MultiERC721ForERC20SwapperDeployer,
MultiERC721ForERC20SwapperProposer
} from "./MultiERC721ForERC20/MultiERC721ForERC20SwapperDeployer.gen.sol";
import {Escrow, IEscrow, ESCROW_MAGIC_NUMBER} from "./Escrow.sol";
import {SwapperDeployerBase} from "./SwapperDeployerBase.sol";
import {Ownable, Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
contract SWAP2Deployer is
Ownable2Step,
ERC721ForNativeSwapperDeployer,
ERC721ForERC20SwapperDeployer,
MultiERC721ForNativeSwapperDeployer,
MultiERC721ForERC20SwapperDeployer
{
error InvalidEscrowContract(address);
Escrow public immutable escrow;
constructor(address initialOwner, Escrow escrow_, address payable feeRecipient, uint16 feeBasisPoints)
Ownable(initialOwner)
{
address escrowA = address(escrow_);
if (escrowA == address(0) || escrowA.code.length == 0 || escrow_.isEscrow() != ESCROW_MAGIC_NUMBER) {
revert InvalidEscrowContract(escrowA);
}
escrow = escrow_;
_setPlatformFee(feeRecipient, feeBasisPoints);
}
struct PlatformFeeConfig {
address payable recipient;
uint16 basisPoints;
}
PlatformFeeConfig public feeConfig;
function setPlatformFee(address payable recipient, uint16 basisPoints) external onlyOwner {
_setPlatformFee(recipient, basisPoints);
}
function _setPlatformFee(address payable recipient, uint16 basisPoints) private {
feeConfig = PlatformFeeConfig({recipient: recipient, basisPoints: basisPoints});
emit PlatformFeeChanged(recipient, basisPoints);
}
function _platformFeeConfig() internal view override returns (address payable, uint16) {
PlatformFeeConfig memory config = feeConfig;
return (config.recipient, config.basisPoints);
}
function _escrow() internal view override returns (IEscrow) {
return escrow;
}
}
abstract contract SWAP2ProposerBase is
ERC721ForNativeSwapperProposer,
ERC721ForERC20SwapperProposer,
MultiERC721ForNativeSwapperProposer,
MultiERC721ForERC20SwapperProposer
{}
contract SWAP2Proposer is SWAP2ProposerBase {
address public immutable deployer;
uint256 public immutable chainId;
constructor(address deployer_, uint256 chainId_) {
deployer = deployer_;
chainId = chainId_;
}
function _swapperDeployer() internal view override returns (address, uint256) {
return (deployer, chainId);
}
}
contract SWAP2 is SWAP2Deployer, SWAP2ProposerBase {
constructor(address initialOwner, Escrow escrow_, address payable feeRecipient, uint16 feeBasisPoints)
SWAP2Deployer(initialOwner, escrow_, feeRecipient, feeBasisPoints)
{}
function _swapperDeployer() internal view override returns (address, uint256) {
return (address(this), _currentChainId());
}
}
文件 32 的 36:SafeERC20.sol
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
error SafeERC20FailedOperation(address token);
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
文件 33 的 36:SwapperBase.sol
pragma solidity 0.8.25;
import {Parties, PayableParties} from "./TypesAndConstants.sol";
contract SwapperBase {
function _asNonPayableParties(PayableParties memory pay) internal pure returns (Parties memory nonPay) {
assembly ("memory-safe") {
nonPay := pay
}
}
function _asNonPayableParties(Parties memory p) internal pure returns (Parties memory) {
return p;
}
}
文件 34 的 36:SwapperDeployerBase.sol
pragma solidity 0.8.25;
import {IEscrow} from "./Escrow.sol";
import {currentChainId} from "./TypesAndConstants.sol";
interface ISwapperDeployerEvents {
event PlatformFeeChanged(address indexed recipient, uint16 basisPoints);
}
abstract contract SwapperDeployerBase is ISwapperDeployerEvents {
function _platformFeeConfig() internal view virtual returns (address payable recipient, uint16 basisPoints);
function _escrow() internal view virtual returns (IEscrow);
function _currentChainId() internal view returns (uint256) {
return currentChainId();
}
}
文件 35 的 36:SwapperProposerBase.sol
pragma solidity 0.8.25;
abstract contract SwapperProposerBase {
function _swapperDeployer() internal view virtual returns (address, uint256 chainId);
}
文件 36 的 36:TypesAndConstants.sol
pragma solidity ^0.8.24;
import {IEscrow} from "./Escrow.sol";
import {Message} from "./ET.sol";
struct Parties {
address seller;
address buyer;
}
struct PayableParties {
address payable seller;
address payable buyer;
}
interface ISwapperEvents {
event Filled(address swapper);
event Cancelled(address swapper);
}
type Action is bytes4;
Action constant FILL = Action.wrap(bytes4(keccak256("FILL")));
Action constant CANCEL = Action.wrap(bytes4(keccak256("CANCEL")));
Message constant CANCEL_MSG = Message.wrap(bytes32(Action.unwrap(CANCEL)));
library ActionMessageLib {
function fillWithFeeConfig(address feeRecipient, uint16 basisPoints) internal pure returns (Message) {
return Message.wrap(bytes32(abi.encodePacked(FILL, feeRecipient, basisPoints)));
}
function cancelWithEscrow(IEscrow escrow_) internal pure returns (Message) {
return Message.wrap(bytes32(abi.encodePacked(CANCEL, escrow_)));
}
function action(Message m) internal pure returns (Action) {
return Action.wrap(bytes4(Message.unwrap(m)));
}
function feeConfig(Message m) internal pure returns (address payable feeRecipient, uint16 basisPoints) {
assert(action(m) == FILL);
uint256 u = uint256(Message.unwrap(m));
feeRecipient = payable(address(bytes20(bytes28(uint224(u)))));
basisPoints = uint16(bytes2(bytes8(uint64(u))));
}
function escrow(Message m) internal pure returns (IEscrow) {
assert(action(m) == CANCEL);
return IEscrow(address(bytes20(bytes28(uint224(uint256(Message.unwrap(m)))))));
}
}
function _eq(Action a, Action b) pure returns (bool) {
return Action.unwrap(a) == Action.unwrap(b);
}
using {_eq as ==} for Action global;
bytes3 constant FILLED_ARTIFACT = 0x5f5ffd;
bytes32 constant FILLED_CODEHASH = keccak256(abi.encodePacked(uint24(FILLED_ARTIFACT)));
bytes3 constant CANCELLED_ARTIFACT = 0x585ffd;
bytes32 constant CANCELLED_CODEHASH = keccak256(abi.encodePacked(uint24(CANCELLED_ARTIFACT)));
bytes32 constant PENDING_CODEHASH = keccak256("");
enum SwapStatus {
Pending,
Filled,
Cancelled,
Invalid
}
function swapStatus(address swapper) view returns (SwapStatus) {
bytes32 h = swapper.codehash;
if (h == 0 || h == PENDING_CODEHASH) {
return SwapStatus.Pending;
}
if (h == FILLED_CODEHASH) {
return SwapStatus.Filled;
}
if (h == CANCELLED_CODEHASH) {
return SwapStatus.Cancelled;
}
return SwapStatus.Invalid;
}
function currentChainId() view returns (uint256 id) {
assembly ("memory-safe") {
id := chainid()
}
}
error OnlyPartyCanCancel();
error UnsupportedAction(Action);
error InsufficientBalance(uint256 actual, uint256 expected);
error ExcessPlatformFee(uint256 fee, uint256 max);
error SwapExpired(uint256 validUntilTime);
{
"compilationTarget": {
"src/SWAP2.sol": "SWAP2"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"contract Escrow","name":"escrow_","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"uint16","name":"feeBasisPoints","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"InvalidEscrowContract","type":"error"},{"inputs":[],"name":"OnlyPartyCanCancel","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"deployed","type":"address"},{"internalType":"address","name":"predicted","type":"address"}],"name":"PredictedAddressMismatch","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapper","type":"address"}],"name":"Cancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"indexed":false,"internalType":"struct ERC721ForERC20Swap","name":"","type":"tuple"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"ERC721ForERC20Proposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"indexed":false,"internalType":"struct ERC721ForNativeSwap","name":"","type":"tuple"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"ERC721ForNativeProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapper","type":"address"}],"name":"Filled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"indexed":false,"internalType":"struct MultiERC721ForERC20Swap","name":"","type":"tuple"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"MultiERC721ForERC20Proposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"indexed":false,"internalType":"struct MultiERC721ForNativeSwap","name":"","type":"tuple"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"MultiERC721ForNativeProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint16","name":"basisPoints","type":"uint16"}],"name":"PlatformFeeChanged","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForERC20Swap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"cancelERC721ForERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForNativeSwap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"cancelERC721ForNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForERC20Swap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"cancelMultiERC721ForERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForNativeSwap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"cancelMultiERC721ForNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"escrow","outputs":[{"internalType":"contract Escrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"etMessage","outputs":[{"internalType":"Message","name":"m","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeConfig","outputs":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint16","name":"basisPoints","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForERC20Swap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"fillERC721ForERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForNativeSwap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"fillERC721ForNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForERC20Swap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"fillMultiERC721ForERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForNativeSwap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"fillMultiERC721ForNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForERC20Swap","name":"swap","type":"tuple"}],"name":"proposeERC721ForERC20","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForNativeSwap","name":"swap","type":"tuple"}],"name":"proposeERC721ForNative","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForERC20Swap","name":"swap","type":"tuple"}],"name":"proposeMultiERC721ForERC20","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForNativeSwap","name":"swap","type":"tuple"}],"name":"proposeMultiERC721ForNative","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint16","name":"basisPoints","type":"uint16"}],"name":"setPlatformFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForERC20Swap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"swapperOfERC721ForERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct ERC721TransferLib.ERC721Token","name":"offer","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct ERC721ForNativeSwap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"swapperOfERC721ForNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"buyer","type":"address"}],"internalType":"struct Parties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"internalType":"struct ERC20Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForERC20Swap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"swapperOfMultiERC721ForERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address payable","name":"seller","type":"address"},{"internalType":"address payable","name":"buyer","type":"address"}],"internalType":"struct PayableParties","name":"parties","type":"tuple"},{"components":[{"internalType":"contract IERC721","name":"addr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"internalType":"struct ERC721TransferLib.MultiERC721Token[]","name":"offer","type":"tuple[]"},{"components":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Disbursement[]","name":"thirdParty","type":"tuple[]"},{"internalType":"uint256","name":"maxPlatformFee","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"internalType":"struct Consideration","name":"consideration","type":"tuple"},{"internalType":"uint256","name":"validUntilTime","type":"uint256"}],"internalType":"struct MultiERC721ForNativeSwap","name":"swap","type":"tuple"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"swapperOfMultiERC721ForNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]