编译器
0.8.19+commit.7dd6d404
文件 1 的 20: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 的 20:BebopPartner.sol
pragma solidity ^0.8.0;
import "./Errors.sol";
abstract contract BebopPartner {
struct PartnerInfo {
uint16 fee;
address beneficiary;
bool registered;
}
mapping(uint64 => PartnerInfo) public partners;
uint16 internal constant HUNDRED_PERCENT = 10000;
constructor(){
partners[0].registered = true;
}
function registerPartner(uint64 partnerId, uint16 fee, address beneficiary) external {
if(partners[partnerId].registered) revert PartnerAlreadyRegistered();
if(fee > HUNDRED_PERCENT) revert PartnerFeeTooHigh();
if (beneficiary == address(0)) revert NullBeneficiary();
partners[partnerId] = PartnerInfo(fee, beneficiary, true);
}
}
文件 3 的 20:BebopSettlement.sol
pragma solidity ^0.8.0;
import "./interface/IBebopSettlement.sol";
import "./base/BebopSigning.sol";
import "./base/BebopTransfer.sol";
import "./libs/Order.sol";
import "./libs/Signature.sol";
import "./libs/Transfer.sol";
contract BebopSettlement is IBebopSettlement, BebopSigning, BebopTransfer {
using SafeERC20 for IERC20;
constructor(address _wrappedNativeToken, address _permit2, address _daiAddress)
BebopTransfer(_wrappedNativeToken, _permit2, _daiAddress) {
}
receive() external payable {}
function swapSingle(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount
) external override payable {
if (msg.sender != order.taker_address) revert InvalidSender();
_executeSingleOrder(order, makerSignature, filledTakerAmount, Commands.SIMPLE_TRANSFER, order.maker_amount);
}
function swapSingleFromContract(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature
) external override payable {
if (msg.sender != order.taker_address) revert InvalidSender();
_executeSingleOrder(
order, makerSignature, IERC20(order.taker_token).balanceOf(address(this)), Commands.TRANSFER_FROM_CONTRACT, order.maker_amount
);
}
function settleSingle(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldSingleQuote calldata takerQuoteInfo,
bytes calldata takerSignature
) external override payable {
_validateTakerSignatureForSingleOrder(order, takerSignature, takerQuoteInfo);
_executeSingleOrder(
order, makerSignature, filledTakerAmount, Commands.SIMPLE_TRANSFER,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmount : order.maker_amount
);
}
function settleSingleAndSignPermit(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldSingleQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.PermitSignature calldata takerPermitSignature
) external override payable {
_validateTakerSignatureForSingleOrder(order, takerSignature, takerQuoteInfo);
_tokenPermit(order.taker_address, order.taker_token, takerPermitSignature);
_executeSingleOrder(
order, makerSignature, filledTakerAmount, Commands.SIMPLE_TRANSFER,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmount : order.maker_amount
);
}
function settleSingleAndSignPermit2(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldSingleQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.Permit2Signature calldata takerPermit2Signature
) external override payable {
_validateTakerSignatureForSingleOrder(order, takerSignature, takerQuoteInfo);
_tokenPermit2(order.taker_address, order.taker_token, takerPermit2Signature);
_executeSingleOrder(
order, makerSignature, filledTakerAmount, Commands.PERMIT2_TRANSFER,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmount : order.maker_amount
);
}
function swapMulti(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount
) external override payable {
if (msg.sender != order.taker_address) revert InvalidSender();
_executeMultiOrder(order, makerSignature, filledTakerAmount, order.maker_amounts);
}
function settleMulti(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldMultiQuote calldata takerQuoteInfo,
bytes calldata takerSignature
) external override payable {
_validateTakerSignatureForMultiOrder(order, takerSignature, takerQuoteInfo);
_executeMultiOrder(
order, makerSignature, filledTakerAmount,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmounts : order.maker_amounts
);
}
function settleMultiAndSignPermit(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldMultiQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.PermitSignature calldata takerPermitSignature
) external override payable {
_validateTakerSignatureForMultiOrder(order, takerSignature, takerQuoteInfo);
_tokenPermitForMultiOrder(order, takerPermitSignature);
_executeMultiOrder(
order, makerSignature, filledTakerAmount,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmounts : order.maker_amounts
);
}
function settleMultiAndSignPermit2(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldMultiQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.MultiTokensPermit2Signature calldata infoPermit2
) external override payable {
_validateTakerSignatureForMultiOrder(order, takerSignature, takerQuoteInfo);
_tokensPermit2ForMultiOrder(order, infoPermit2);
_executeMultiOrder(
order, makerSignature, filledTakerAmount,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmounts : order.maker_amounts
);
}
function swapAggregate(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount
) external override payable {
if (msg.sender != order.taker_address) revert InvalidSender();
_executeAggregateOrder(order, makersSignatures, filledTakerAmount, order.maker_amounts);
}
function settleAggregate(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
Transfer.OldAggregateQuote calldata takerQuoteInfo,
bytes calldata takerSignature
) external override payable {
_validateTakerSignatureForAggregateOrder(order, takerSignature, takerQuoteInfo);
_executeAggregateOrder(
order, makersSignatures, filledTakerAmount,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmounts : order.maker_amounts
);
}
function settleAggregateAndSignPermit(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
Transfer.OldAggregateQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.PermitSignature calldata takerPermitSignature
) external override payable {
_validateTakerSignatureForAggregateOrder(order, takerSignature, takerQuoteInfo);
_tokenPermitForAggregateOrder(order, takerPermitSignature);
_executeAggregateOrder(
order, makersSignatures, filledTakerAmount,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmounts : order.maker_amounts
);
}
function settleAggregateAndSignPermit2(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
Transfer.OldAggregateQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.MultiTokensPermit2Signature calldata infoPermit2
) external override payable {
_validateTakerSignatureForAggregateOrder(order, takerSignature, takerQuoteInfo);
_tokensPermit2ForAggregateOrder(order, infoPermit2);
_executeAggregateOrder(
order, makersSignatures, filledTakerAmount,
takerQuoteInfo.useOldAmount ? takerQuoteInfo.makerAmounts : order.maker_amounts
);
}
function _executeSingleOrder(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
bytes1 takerTransferCommand,
uint256 updatedMakerAmount
) internal {
_validateSingleOrder(order, makerSignature);
(uint128 eventId, uint64 partnerId) = Order.extractFlags(order.flags);
(bool takerHasNative, bool makerHasNative, bool takerUsingPermit2) = Order.extractSingleOrderCommands(order.packed_commands);
if (takerTransferCommand == Commands.TRANSFER_FROM_CONTRACT && takerHasNative){
filledTakerAmount = address(this).balance;
}
_transferToken(
order.taker_address, order.maker_address, order.taker_token,
filledTakerAmount == 0 || filledTakerAmount > order.taker_amount ? order.taker_amount : filledTakerAmount,
takerHasNative ? Commands.NATIVE_TRANSFER : (takerUsingPermit2 ? Commands.PERMIT2_TRANSFER : takerTransferCommand),
takerHasNative ? Transfer.Action.Wrap : Transfer.Action.None, 0
);
uint256 newMakerAmount = updatedMakerAmount;
if (filledTakerAmount != 0 && filledTakerAmount < order.taker_amount){
newMakerAmount = (updatedMakerAmount * filledTakerAmount) / order.taker_amount;
}
(bool makerUsingPermit2, ) = Signature.extractMakerFlags(makerSignature.flags);
_transferToken(
order.maker_address, order.receiver, order.maker_token, newMakerAmount,
makerUsingPermit2 ? Commands.PERMIT2_TRANSFER : Commands.SIMPLE_TRANSFER,
makerHasNative ? Transfer.Action.Unwrap : Transfer.Action.None, partnerId
);
emit BebopOrder(eventId);
}
function _executeMultiOrder(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
uint256[] calldata updatedMakerAmounts
) internal {
_validateMultiOrder(order, makerSignature, filledTakerAmount);
(uint128 eventId, uint64 partnerId) = Order.extractFlags(order.flags);
(bool makerUsingPermit2, ) = Signature.extractMakerFlags(makerSignature.flags);
if (order.taker_tokens.length > 1){
_transferTakerTokens(order);
_transferToken(
order.maker_address, order.receiver, order.maker_tokens[0], updatedMakerAmounts[0],
makerUsingPermit2 ? Commands.PERMIT2_TRANSFER : Commands.SIMPLE_TRANSFER,
order.commands[0] == Commands.NATIVE_TRANSFER ? Transfer.Action.Unwrap : Transfer.Action.None, partnerId
);
} else {
bytes1 takerCommand = order.commands[order.maker_tokens.length];
_transferToken(
order.taker_address, order.maker_address, order.taker_tokens[0],
filledTakerAmount == 0 || filledTakerAmount > order.taker_amounts[0] ?
order.taker_amounts[0] : filledTakerAmount,
takerCommand, takerCommand == Commands.NATIVE_TRANSFER ? Transfer.Action.Wrap : Transfer.Action.None, 0
);
uint[] memory makerAmounts = updatedMakerAmounts;
if (filledTakerAmount > 0 && filledTakerAmount < order.taker_amounts[0]){
for (uint j; j < updatedMakerAmounts.length; ++j){
makerAmounts[j] = updatedMakerAmounts[j] * filledTakerAmount / order.taker_amounts[0];
}
}
uint nativeToTaker = _transferMakerTokens(
order.maker_address, order.receiver, order.maker_tokens, makerAmounts, makerUsingPermit2,
order.commands, partnerId
);
if (nativeToTaker > 0){
IWETH(WRAPPED_NATIVE_TOKEN).withdraw(nativeToTaker);
(bool sent,) = order.receiver.call{value: nativeToTaker}("");
if (!sent) revert FailedToSendNativeToken();
}
}
emit BebopOrder(eventId);
}
function _executeAggregateOrder(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
uint256[][] calldata updatedMakerAmounts
) internal {
_validateAggregateOrder(order, makersSignatures);
(uint quoteTakerAmount, Transfer.LengthsInfo memory lenInfo) = _getAggregateOrderInfo(order, filledTakerAmount);
Transfer.IndicesInfo memory indices = Transfer.IndicesInfo(0, 0, 0);
Transfer.NativeTokens memory nativeTokens = Transfer.NativeTokens(0, 0);
Transfer.Pending[] memory pendingTransfers = new Transfer.Pending[](lenInfo.pendingTransfersLen);
IPermit2.AllowanceTransferDetails[] memory batchTransferDetails = new IPermit2.AllowanceTransferDetails[](lenInfo.permit2Len);
for (uint i; i < order.maker_tokens.length; ++i){
(bool makerUsingPermit2, ) = Signature.extractMakerFlags(makersSignatures[i].flags);
uint[] memory makerAmounts = updatedMakerAmounts[i];
if (filledTakerAmount > 0 && filledTakerAmount < quoteTakerAmount){
for (uint j; j < updatedMakerAmounts[i].length; ++j){
makerAmounts[j] = updatedMakerAmounts[i][j] * filledTakerAmount / quoteTakerAmount;
}
}
nativeTokens.toTaker += _transferMakerTokens(
order.maker_addresses[i], order.receiver, order.maker_tokens[i], makerAmounts,
makerUsingPermit2, BytesLib.slice(order.commands, indices.commandsInd, order.maker_tokens[i].length),
Order.extractPartnerId(order.flags)
);
indices.commandsInd += order.maker_tokens[i].length;
_transferTakerTokensForAggregateOrder(
order, i, filledTakerAmount, quoteTakerAmount, indices, nativeTokens, pendingTransfers, batchTransferDetails
);
indices.commandsInd += order.taker_tokens[i].length;
}
if (indices.pendingTransfersInd != lenInfo.pendingTransfersLen) revert InvalidPendingTransfersLength();
if (indices.permit2Ind != lenInfo.permit2Len) revert InvalidPermit2TransfersLength();
if (lenInfo.permit2Len > 0) {
PERMIT2.transferFrom(batchTransferDetails);
}
if (lenInfo.pendingTransfersLen > 0) {
if (nativeTokens.toMakers > 0){
if (msg.value < nativeTokens.toMakers) revert NotEnoughNativeToken();
IWETH(WRAPPED_NATIVE_TOKEN).deposit{value: nativeTokens.toMakers}();
}
for (uint i; i < pendingTransfers.length; ++i) {
if (pendingTransfers[i].amount > 0) {
IERC20(pendingTransfers[i].token).safeTransfer(
pendingTransfers[i].to, pendingTransfers[i].amount
);
}
}
}
if (nativeTokens.toTaker > 0) {
IWETH(WRAPPED_NATIVE_TOKEN).withdraw(nativeTokens.toTaker);
(bool sent,) = order.receiver.call{value: nativeTokens.toTaker}("");
if (!sent) revert FailedToSendNativeToken();
}
emit BebopOrder(Order.extractEventId(order.flags));
}
}
文件 4 的 20:BebopSigning.sol
pragma solidity ^0.8.0;
import "../libs/Order.sol";
import "../libs/Signature.sol";
import "../libs/common/BytesLib.sol";
import "./Errors.sol";
import "lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol";
import "../libs/Transfer.sol";
abstract contract BebopSigning {
event OrderSignerRegistered(address maker, address signer, bool allowed);
bytes32 private constant DOMAIN_NAME = keccak256("BebopSettlement");
bytes32 private constant DOMAIN_VERSION = keccak256("2");
bytes4 private constant EIP1271_MAGICVALUE = 0x1626ba7e;
uint256 private constant ETH_SIGN_HASH_PREFIX = 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000;
bytes32 private constant EIP712_DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
bytes32 private constant AGGREGATED_ORDER_TYPE_HASH = 0xe850f4ac05cb765eff6f120037e6d3286f8f71aaedad7f9f242af69d53091265;
bytes32 private constant MULTI_ORDER_TYPE_HASH = 0x34728ce057ec73e3b4f0871dced9cc875f5b1aece9fd07891e156fe852a858d9;
bytes32 private constant SINGLE_ORDER_TYPE_HASH = 0xe34225bc7cd92038d42c258ee3ff66d30f9387dd932213ba32a52011df0603fc;
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
mapping(address => mapping(uint256 => uint256)) private makerNonceValidator;
mapping(address => mapping(address => bool)) private orderSignerRegistry;
constructor(){
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = keccak256(
abi.encode(EIP712_DOMAIN_TYPEHASH, DOMAIN_NAME, DOMAIN_VERSION, block.chainid, address(this))
);
}
function DOMAIN_SEPARATOR() public view returns (bytes32) {
return block.chainid == _CACHED_CHAIN_ID
? _CACHED_DOMAIN_SEPARATOR
: keccak256(
abi.encode(EIP712_DOMAIN_TYPEHASH, DOMAIN_NAME, DOMAIN_VERSION, block.chainid, address(this))
);
}
function registerAllowedOrderSigner(address signer, bool allowed) external {
orderSignerRegistry[msg.sender][signer] = allowed;
emit OrderSignerRegistered(msg.sender, signer, allowed);
}
function hashSingleOrder(
Order.Single calldata order, uint64 partnerId, uint256 updatedMakerAmount, uint256 updatedMakerNonce
) public view returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), keccak256(
abi.encode(
SINGLE_ORDER_TYPE_HASH, partnerId, order.expiry, order.taker_address, order.maker_address,
updatedMakerNonce != 0 ? updatedMakerNonce : order.maker_nonce, order.taker_token, order.maker_token,
order.taker_amount, updatedMakerAmount != 0 ? updatedMakerAmount : order.maker_amount, order.receiver,
order.packed_commands
)
)));
}
function hashMultiOrder(
Order.Multi memory order, uint64 partnerId, uint256[] calldata updatedMakerAmounts, uint256 updatedMakerNonce
) public view returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), keccak256(
abi.encode(
MULTI_ORDER_TYPE_HASH, partnerId, order.expiry, order.taker_address, order.maker_address, updatedMakerNonce,
keccak256(abi.encodePacked(order.taker_tokens)), keccak256(abi.encodePacked(order.maker_tokens)),
keccak256(abi.encodePacked(order.taker_amounts)), keccak256(abi.encodePacked(updatedMakerAmounts)),
order.receiver, keccak256(order.commands)
)
)));
}
function hashAggregateOrder(
Order.Aggregate calldata order, uint64 partnerId, uint256[][] calldata updatedMakerAmounts, uint256[] calldata updatedMakerNonces
) public view returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), keccak256(
abi.encode(
AGGREGATED_ORDER_TYPE_HASH, partnerId, order.expiry, order.taker_address,
keccak256(abi.encodePacked(order.maker_addresses)), keccak256(abi.encodePacked(updatedMakerNonces)),
keccak256(_encodeTightlyPackedNested(order.taker_tokens)), keccak256(_encodeTightlyPackedNested(order.maker_tokens)),
keccak256(_encodeTightlyPackedNestedInt(order.taker_amounts)), keccak256(_encodeTightlyPackedNestedInt(updatedMakerAmounts)),
order.receiver, keccak256(order.commands)
)
)));
}
function _validateSignature(
address validationAddress, bytes32 hash, bytes calldata signature, Signature.Type signatureType, bool isMaker
) internal view {
if (signatureType == Signature.Type.EIP712) {
(bytes32 r, bytes32 s, uint8 v) = Signature.getRsv(signature);
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) revert OrderInvalidSigner();
if (signer != validationAddress && (!isMaker || !orderSignerRegistry[validationAddress][signer])) {
revert InvalidEIP721Signature();
}
} else if (signatureType == Signature.Type.EIP1271) {
if (IERC1271(validationAddress).isValidSignature(hash, signature) != EIP1271_MAGICVALUE){
revert InvalidEIP1271Signature();
}
} else if (signatureType == Signature.Type.ETHSIGN) {
bytes32 ethSignHash;
assembly {
mstore(0, ETH_SIGN_HASH_PREFIX)
mstore(28, hash)
ethSignHash := keccak256(0, 60)
}
(bytes32 r, bytes32 s, uint8 v) = Signature.getRsv(signature);
address signer = ecrecover(ethSignHash, v, r, s);
if (signer == address(0)) revert OrderInvalidSigner();
if (signer != validationAddress && (!isMaker || !orderSignerRegistry[validationAddress][signer])) {
revert InvalidETHSIGNSignature();
}
} else {
revert InvalidSignatureType();
}
}
function _encodeTightlyPackedNestedInt(uint256[][] calldata _nested_array) private pure returns (bytes memory encoded) {
uint nested_array_length = _nested_array.length;
for (uint i; i < nested_array_length; ++i) {
encoded = abi.encodePacked(encoded, keccak256(abi.encodePacked(_nested_array[i])));
}
return encoded;
}
function _encodeTightlyPackedNested(address[][] calldata _nested_array) private pure returns (bytes memory encoded) {
uint nested_array_length = _nested_array.length;
for (uint i; i < nested_array_length; ++i) {
encoded = abi.encodePacked(encoded, keccak256(abi.encodePacked(_nested_array[i])));
}
return encoded;
}
function _invalidateOrder(address maker, uint256 nonce) private {
if (nonce == 0) revert ZeroNonce();
uint256 invalidatorSlot = nonce >> 8;
uint256 invalidatorBit = 1 << (nonce & 0xff);
mapping(uint256 => uint256) storage invalidatorStorage = makerNonceValidator[maker];
uint256 invalidator = invalidatorStorage[invalidatorSlot];
if (invalidator & invalidatorBit == invalidatorBit) revert InvalidNonce();
invalidatorStorage[invalidatorSlot] = invalidator | invalidatorBit;
}
function _validateSingleOrder(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature
) internal {
(, Signature.Type signatureType) = Signature.extractMakerFlags(makerSignature.flags);
_validateSignature(
order.maker_address, hashSingleOrder(order, Order.extractPartnerId(order.flags), 0, 0),
makerSignature.signatureBytes, signatureType, true
);
_invalidateOrder(order.maker_address, order.maker_nonce);
if (order.expiry <= block.timestamp) revert OrderExpired();
}
function _validateMultiOrder(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount
) internal {
(, Signature.Type signatureType) = Signature.extractMakerFlags(makerSignature.flags);
_validateSignature(
order.maker_address,
hashMultiOrder(order, Order.extractPartnerId(order.flags), order.maker_amounts, order.maker_nonce),
makerSignature.signatureBytes, signatureType, true
);
_invalidateOrder(order.maker_address, order.maker_nonce);
if (
order.taker_tokens.length != order.taker_amounts.length || order.maker_tokens.length != order.maker_amounts.length
) revert TokensLengthsMismatch();
if (order.commands.length != order.taker_tokens.length + order.maker_tokens.length) revert InvalidCommandsLength();
if (order.taker_tokens.length != 1 && order.maker_tokens.length != 1) revert ManyToManyNotSupported();
if (order.taker_tokens.length > 1 && filledTakerAmount != 0){
revert PartialFillNotSupported();
}
if (order.expiry <= block.timestamp) revert OrderExpired();
}
function _validateAggregateOrder(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures
) internal {
uint makersNum = makersSignatures.length;
if (
order.maker_addresses.length != makersNum || order.maker_nonces.length != makersNum
|| order.taker_tokens.length != makersNum || order.maker_tokens.length != makersNum
|| order.taker_amounts.length != makersNum || order.maker_amounts.length != makersNum
) revert OrdersLengthsMismatch();
uint tokenTransfers;
for (uint i; i < makersNum; ++i) {
if (order.maker_tokens[i].length != order.maker_amounts[i].length
|| order.taker_tokens[i].length != order.taker_amounts[i].length)
revert TokensLengthsMismatch();
Order.Multi memory partialAggregateOrder = Order.Multi(
order.expiry, order.taker_address, order.maker_addresses[i], order.maker_nonces[i],
order.taker_tokens[i], order.maker_tokens[i], order.taker_amounts[i], order.maker_amounts[i],
order.receiver, BytesLib.slice(
order.commands, tokenTransfers, order.maker_tokens[i].length + order.taker_tokens[i].length
), 0
);
bytes32 multiOrderHash = hashMultiOrder(
partialAggregateOrder, Order.extractPartnerId(order.flags), order.maker_amounts[i], order.maker_nonces[i]
);
(, Signature.Type signatureType) = Signature.extractMakerFlags(makersSignatures[i].flags);
_validateSignature(
order.maker_addresses[i], multiOrderHash, makersSignatures[i].signatureBytes, signatureType, true
);
_invalidateOrder(order.maker_addresses[i], order.maker_nonces[i]);
tokenTransfers += order.maker_tokens[i].length + order.taker_tokens[i].length;
}
if (tokenTransfers != order.commands.length) revert CommandsLengthsMismatch();
if (order.expiry <= block.timestamp) revert OrderExpired();
}
function _validateTakerSignatureForSingleOrder(
Order.Single calldata order, bytes calldata takerSignature, Transfer.OldSingleQuote calldata takerQuoteInfo
) internal {
if (order.maker_amount < takerQuoteInfo.makerAmount) revert UpdatedMakerAmountsTooLow();
if (takerQuoteInfo.makerAmount == 0) revert ZeroMakerAmount();
if (takerQuoteInfo.makerNonce != order.maker_nonce){
_invalidateOrder(order.maker_address, takerQuoteInfo.makerNonce);
}
if (msg.sender != order.taker_address){
Signature.Type signatureType = Order.extractSignatureType(order.flags);
_validateSignature(
order.taker_address,
hashSingleOrder(order, Order.extractPartnerId(order.flags), takerQuoteInfo.makerAmount, takerQuoteInfo.makerNonce),
takerSignature, signatureType, false
);
}
}
function _validateTakerSignatureForMultiOrder(
Order.Multi calldata order, bytes calldata takerSignature, Transfer.OldMultiQuote calldata takerQuoteInfo
) internal {
if (takerQuoteInfo.makerAmounts.length != order.maker_amounts.length) revert MakerAmountsLengthsMismatch();
for (uint i; i < takerQuoteInfo.makerAmounts.length; ++i){
if (takerQuoteInfo.makerAmounts[i] == 0) revert ZeroMakerAmount();
if (order.maker_amounts[i] < takerQuoteInfo.makerAmounts[i]) revert UpdatedMakerAmountsTooLow();
}
if (takerQuoteInfo.makerNonce != order.maker_nonce){
_invalidateOrder(order.maker_address, takerQuoteInfo.makerNonce);
}
if (msg.sender != order.taker_address){
Signature.Type signatureType = Order.extractSignatureType(order.flags);
_validateSignature(
order.taker_address,
hashMultiOrder(order, Order.extractPartnerId(order.flags), takerQuoteInfo.makerAmounts, takerQuoteInfo.makerNonce),
takerSignature, signatureType, false
);
}
}
function _validateTakerSignatureForAggregateOrder(
Order.Aggregate calldata order, bytes calldata takerSignature, Transfer.OldAggregateQuote calldata takerQuoteInfo
) internal {
if (takerQuoteInfo.makerAmounts.length != order.maker_amounts.length) revert MakerAmountsLengthsMismatch();
for (uint i; i < order.maker_amounts.length; ++i){
if (takerQuoteInfo.makerAmounts[i].length != order.maker_amounts[i].length) revert MakerAmountsLengthsMismatch();
for (uint j; j < order.maker_amounts[i].length; ++j){
if (order.maker_amounts[i][j] < takerQuoteInfo.makerAmounts[i][j]) revert UpdatedMakerAmountsTooLow();
}
if (takerQuoteInfo.makerNonces[i] != order.maker_nonces[i]){
_invalidateOrder(order.maker_addresses[i], takerQuoteInfo.makerNonces[i]);
}
}
if (msg.sender != order.taker_address){
Signature.Type signatureType = Order.extractSignatureType(order.flags);
_validateSignature(
order.taker_address,
hashAggregateOrder(order, Order.extractPartnerId(order.flags), takerQuoteInfo.makerAmounts, takerQuoteInfo.makerNonces),
takerSignature, signatureType, false
);
}
}
}
文件 5 的 20:BebopTransfer.sol
pragma solidity ^0.8.0;
import "../interface/IDaiLikePermit.sol";
import "../interface/IPermit2.sol";
import "../interface/IWETH.sol";
import "../libs/Order.sol";
import "../libs/Signature.sol";
import "../libs/Transfer.sol";
import "../libs/Commands.sol";
import "../libs/common/SafeCast160.sol";
import "./BebopSigning.sol";
import "./BebopPartner.sol";
import "./Errors.sol";
import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
abstract contract BebopTransfer is BebopPartner {
using SafeERC20 for IERC20;
address internal immutable WRAPPED_NATIVE_TOKEN;
address internal immutable DAI_TOKEN;
IPermit2 internal immutable PERMIT2;
uint private immutable _chainId;
function _getChainId() private view returns (uint256 id) {
assembly {
id := chainid()
}
}
constructor(address _wrappedNativeToken, address _permit2, address _daiAddress) {
WRAPPED_NATIVE_TOKEN = _wrappedNativeToken;
DAI_TOKEN = _daiAddress;
PERMIT2 = IPermit2(_permit2);
_chainId = _getChainId();
}
function _getAggregateOrderInfo(
Order.Aggregate calldata order,
uint256 filledTakerAmount
) internal pure returns (uint quoteTakerAmount, Transfer.LengthsInfo memory lenInfo){
uint commandsInd;
address tokenAddress = order.taker_tokens[0][0];
for (uint i; i < order.taker_tokens.length; ++i){
commandsInd += order.maker_tokens[i].length;
for (uint j; j < order.taker_tokens[i].length; ++j) {
bytes1 curCommand = order.commands[commandsInd + j];
if (curCommand != Commands.TRANSFER_FROM_CONTRACT){
if (filledTakerAmount > 0){
quoteTakerAmount += order.taker_amounts[i][j];
if (tokenAddress != order.taker_tokens[i][j]){
revert PartialFillNotSupported();
}
}
if (curCommand == Commands.NATIVE_TRANSFER) {
++lenInfo.pendingTransfersLen;
} else if (curCommand == Commands.PERMIT2_TRANSFER || curCommand == Commands.CALL_PERMIT2_THEN_TRANSFER) {
++lenInfo.permit2Len;
}
} else {
++lenInfo.pendingTransfersLen;
}
}
commandsInd += order.taker_tokens[i].length;
}
}
function _transferToken(
address from, address to, address token, uint256 amount, bytes1 command, Transfer.Action action, uint64 partnerId
) internal {
if (action == Transfer.Action.Wrap){
if (token != WRAPPED_NATIVE_TOKEN) revert WrongWrappedTokenAddress();
IWETH(WRAPPED_NATIVE_TOKEN).deposit{value: amount}();
}
uint fee;
PartnerInfo memory partnerInfo;
if (partnerId != 0){
partnerInfo = partners[partnerId];
if (partnerInfo.registered && partnerInfo.fee > 0){
fee = amount * partnerInfo.fee / HUNDRED_PERCENT;
}
}
address receiver = action == Transfer.Action.Unwrap ? address(this) : to;
if (command == Commands.SIMPLE_TRANSFER || command == Commands.CALL_PERMIT_THEN_TRANSFER){
if (fee > 0){
IERC20(token).safeTransferFrom(from, partnerInfo.beneficiary, fee);
amount -= fee;
}
IERC20(token).safeTransferFrom(from, receiver, amount);
} else if (command == Commands.PERMIT2_TRANSFER || command == Commands.CALL_PERMIT2_THEN_TRANSFER){
if (fee > 0){
amount -= fee;
IPermit2.AllowanceTransferDetails[] memory batchTransferDetails = new IPermit2.AllowanceTransferDetails[](2);
batchTransferDetails[0] = IPermit2.AllowanceTransferDetails(from, partnerInfo.beneficiary, SafeCast160.toUint160(fee), token);
batchTransferDetails[1] = IPermit2.AllowanceTransferDetails(from, receiver, SafeCast160.toUint160(amount), token);
PERMIT2.transferFrom(batchTransferDetails);
} else {
PERMIT2.transferFrom(from, receiver, SafeCast160.toUint160(amount), token);
}
} else if (command == Commands.TRANSFER_FROM_CONTRACT || command == Commands.NATIVE_TRANSFER){
IERC20(token).safeTransfer(to, amount);
} else {
revert InvalidCommand();
}
if (action == Transfer.Action.Unwrap){
if (token != WRAPPED_NATIVE_TOKEN) revert WrongWrappedTokenAddress();
IWETH(WRAPPED_NATIVE_TOKEN).withdraw(amount);
(bool sent,) = to.call{value: amount}("");
if (!sent) revert FailedToSendNativeToken();
}
}
function _transferTakerTokens(Order.Multi calldata order) internal {
IPermit2.AllowanceTransferDetails[] memory batchTransferDetails;
uint permit2Ind;
for (uint i; i < order.taker_tokens.length; ++i) {
bytes1 command = order.commands[i + order.maker_tokens.length];
if (command == Commands.SIMPLE_TRANSFER || command == Commands.CALL_PERMIT_THEN_TRANSFER){
IERC20(order.taker_tokens[i]).safeTransferFrom(
order.taker_address, order.maker_address, order.taker_amounts[i]
);
} else if (command == Commands.PERMIT2_TRANSFER || command == Commands.CALL_PERMIT2_THEN_TRANSFER){
if (batchTransferDetails.length == 0){
batchTransferDetails = new IPermit2.AllowanceTransferDetails[](order.taker_tokens.length - i);
}
batchTransferDetails[permit2Ind++] = IPermit2.AllowanceTransferDetails({
from: order.taker_address,
to: order.maker_address,
amount: SafeCast160.toUint160(order.taker_amounts[i]),
token: order.taker_tokens[i]
});
continue;
} else if (command == Commands.NATIVE_TRANSFER) {
if (order.taker_tokens[i] != WRAPPED_NATIVE_TOKEN) revert WrongWrappedTokenAddress();
IWETH(WRAPPED_NATIVE_TOKEN).deposit{value: order.taker_amounts[i]}();
IERC20(WRAPPED_NATIVE_TOKEN).safeTransfer(order.maker_address, order.taker_amounts[i]);
} else {
revert InvalidCommand();
}
if (batchTransferDetails.length > 0){
assembly {mstore(batchTransferDetails, sub(mload(batchTransferDetails), 1))}
}
}
if (batchTransferDetails.length > 0){
PERMIT2.transferFrom(batchTransferDetails);
}
}
function _transferMakerTokens(
address from,
address to,
address[] calldata maker_tokens,
uint256[] memory maker_amounts,
bool usingPermit2,
bytes memory makerCommands,
uint64 partnerId
) internal returns (uint256) {
uint256 nativeToTaker;
IPermit2.AllowanceTransferDetails[] memory batchTransferDetails;
uint batchInd;
bool hasPartnerFee = partnerId != 0;
PartnerInfo memory partnerInfo;
if (hasPartnerFee){
partnerInfo = partners[partnerId];
hasPartnerFee = partnerInfo.registered && partnerInfo.fee > 0;
}
for (uint j; j < maker_tokens.length; ++j) {
uint256 amount = maker_amounts[j];
address receiver = to;
if (makerCommands[j] != Commands.SIMPLE_TRANSFER){
if (makerCommands[j] == Commands.TRANSFER_TO_CONTRACT) {
receiver = address(this);
} else if (makerCommands[j] == Commands.NATIVE_TRANSFER) {
if (maker_tokens[j] != WRAPPED_NATIVE_TOKEN) revert WrongWrappedTokenAddress();
nativeToTaker += amount;
receiver = address(this);
} else {
revert InvalidCommand();
}
}
if (usingPermit2) {
if (batchTransferDetails.length == 0){
batchTransferDetails = new IPermit2.AllowanceTransferDetails[](hasPartnerFee ? 2 * maker_tokens.length : maker_tokens.length);
}
if (hasPartnerFee){
if (makerCommands[j] != Commands.TRANSFER_TO_CONTRACT){
uint256 fee = amount * partnerInfo.fee / HUNDRED_PERCENT;
if (fee > 0){
batchTransferDetails[batchInd++] = IPermit2.AllowanceTransferDetails({
from: from,
to: partnerInfo.beneficiary,
amount: SafeCast160.toUint160(fee),
token: maker_tokens[j]
});
amount -= fee;
if (makerCommands[j] == Commands.NATIVE_TRANSFER){
nativeToTaker -= fee;
}
} else {
assembly {mstore(batchTransferDetails, sub(mload(batchTransferDetails), 1))}
}
} else {
assembly {mstore(batchTransferDetails, sub(mload(batchTransferDetails), 1))}
}
}
batchTransferDetails[batchInd++] = IPermit2.AllowanceTransferDetails({
from: from,
to: receiver,
amount: SafeCast160.toUint160(amount),
token: maker_tokens[j]
});
} else {
if (hasPartnerFee && makerCommands[j] != Commands.TRANSFER_TO_CONTRACT){
uint256 fee = amount * partnerInfo.fee / HUNDRED_PERCENT;
if (fee > 0){
IERC20(maker_tokens[j]).safeTransferFrom(from, partnerInfo.beneficiary, fee);
amount -= fee;
if (makerCommands[j] == Commands.NATIVE_TRANSFER){
nativeToTaker -= fee;
}
}
}
IERC20(maker_tokens[j]).safeTransferFrom(from, receiver, amount);
}
}
if (usingPermit2){
if (batchInd != batchTransferDetails.length) revert InvalidPermit2Commands();
PERMIT2.transferFrom(batchTransferDetails);
}
return nativeToTaker;
}
function _transferTakerTokensForAggregateOrder(
Order.Aggregate calldata order,
uint256 i,
uint256 filledTakerAmount,
uint256 quoteTakerAmount,
Transfer.IndicesInfo memory indices,
Transfer.NativeTokens memory nativeTokens,
Transfer.Pending[] memory pendingTransfers,
IPermit2.AllowanceTransferDetails[] memory batchTransferDetails
) internal {
for (uint k; k < order.taker_tokens[i].length; ++k) {
uint currentTakerAmount = filledTakerAmount > 0 && filledTakerAmount < quoteTakerAmount ?
order.taker_amounts[i][k] * filledTakerAmount / quoteTakerAmount : order.taker_amounts[i][k];
bytes1 curCommand = order.commands[indices.commandsInd + k];
if (curCommand == Commands.SIMPLE_TRANSFER || curCommand == Commands.CALL_PERMIT_THEN_TRANSFER){
IERC20(order.taker_tokens[i][k]).safeTransferFrom(
order.taker_address, order.maker_addresses[i], currentTakerAmount
);
} else if (curCommand == Commands.PERMIT2_TRANSFER || curCommand == Commands.CALL_PERMIT2_THEN_TRANSFER){
batchTransferDetails[indices.permit2Ind++] = IPermit2.AllowanceTransferDetails({
from: order.taker_address,
to: order.maker_addresses[i],
amount: SafeCast160.toUint160(currentTakerAmount),
token: order.taker_tokens[i][k]
});
} else if (curCommand == Commands.NATIVE_TRANSFER) {
if (order.taker_tokens[i][k] != WRAPPED_NATIVE_TOKEN) revert WrongWrappedTokenAddress();
nativeTokens.toMakers += currentTakerAmount;
pendingTransfers[indices.pendingTransfersInd++] = Transfer.Pending(
order.taker_tokens[i][k], order.maker_addresses[i], currentTakerAmount
);
} else if (curCommand == Commands.TRANSFER_FROM_CONTRACT){
pendingTransfers[indices.pendingTransfersInd++] = Transfer.Pending(
order.taker_tokens[i][k], order.maker_addresses[i], currentTakerAmount
);
} else {
revert InvalidCommand();
}
}
}
function _tokenPermit(
address takerAddress, address tokenAddress, Signature.PermitSignature calldata takerPermitSignature
) internal {
(bytes32 r, bytes32 s, uint8 v) = Signature.getRsv(takerPermitSignature.signatureBytes);
if (tokenAddress == DAI_TOKEN){
if (_chainId == 137){
IDaiLikePermit(tokenAddress).permit(
takerAddress, address(this), IDaiLikePermit(tokenAddress).getNonce(takerAddress), takerPermitSignature.deadline, true, v, r, s
);
} else {
IDaiLikePermit(tokenAddress).permit(
takerAddress, address(this), IERC20Permit(tokenAddress).nonces(takerAddress), takerPermitSignature.deadline, true, v, r, s
);
}
} else {
IERC20Permit(tokenAddress).permit(takerAddress, address(this), type(uint).max, takerPermitSignature.deadline, v, r, s);
}
}
function _tokenPermit2(
address takerAddress, address tokenAddress, Signature.Permit2Signature calldata takerPermit2Signature
) internal {
IPermit2.PermitDetails[] memory permitBatch = new IPermit2.PermitDetails[](1);
permitBatch[0] = IPermit2.PermitDetails(
tokenAddress, type(uint160).max, takerPermit2Signature.deadline, takerPermit2Signature.nonce
);
PERMIT2.permit(
takerAddress,
IPermit2.PermitBatch(permitBatch, address(this), takerPermit2Signature.deadline),
takerPermit2Signature.signatureBytes
);
}
function _tokenPermitForMultiOrder(
Order.Multi calldata order, Signature.PermitSignature calldata takerPermitSignature
) internal {
uint commandsInd = order.maker_tokens.length;
for (uint i; i < order.taker_tokens.length; ++i){
if (order.commands[commandsInd++] == Commands.CALL_PERMIT_THEN_TRANSFER){
_tokenPermit(order.taker_address, order.taker_tokens[i], takerPermitSignature);
return;
}
}
}
function _tokensPermit2ForMultiOrder(
Order.Multi calldata order, Signature.MultiTokensPermit2Signature calldata infoPermit2
) internal {
uint commandsInd = order.maker_tokens.length;
uint batchToApproveInd;
IPermit2.PermitDetails[] memory batchToApprove = new IPermit2.PermitDetails[](infoPermit2.nonces.length);
for (uint i; i < order.taker_tokens.length; ++i){
if (order.commands[commandsInd++] == Commands.CALL_PERMIT2_THEN_TRANSFER){
batchToApprove[batchToApproveInd] = IPermit2.PermitDetails(
order.taker_tokens[i], type(uint160).max, infoPermit2.deadline, infoPermit2.nonces[batchToApproveInd]
);
++batchToApproveInd;
}
}
if (batchToApproveInd != batchToApprove.length) revert InvalidPermit2Commands();
PERMIT2.permit(
order.taker_address,
IPermit2.PermitBatch(batchToApprove, address(this), infoPermit2.deadline),
infoPermit2.signatureBytes
);
}
function _tokenPermitForAggregateOrder(
Order.Aggregate calldata order, Signature.PermitSignature calldata takerPermitSignature
) internal {
uint commandsInd;
for (uint i; i < order.taker_tokens.length; ++i){
commandsInd += order.maker_tokens[i].length;
for (uint j; j < order.taker_tokens[i].length; ++j) {
if (order.commands[commandsInd++] == Commands.CALL_PERMIT_THEN_TRANSFER){
_tokenPermit(order.taker_address, order.taker_tokens[i][j], takerPermitSignature);
return;
}
}
}
}
function _tokensPermit2ForAggregateOrder(
Order.Aggregate calldata order, Signature.MultiTokensPermit2Signature calldata infoPermit2
) internal {
uint commandsInd;
uint batchToApproveInd;
IPermit2.PermitDetails[] memory batchToApprove = new IPermit2.PermitDetails[](infoPermit2.nonces.length);
for (uint i; i < order.taker_tokens.length; ++i){
commandsInd += order.maker_tokens[i].length;
for (uint j; j < order.taker_tokens[i].length; ++j) {
if (order.commands[commandsInd++] == Commands.CALL_PERMIT2_THEN_TRANSFER){
batchToApprove[batchToApproveInd] = IPermit2.PermitDetails(
order.taker_tokens[i][j], type(uint160).max, infoPermit2.deadline, infoPermit2.nonces[batchToApproveInd]
);
++batchToApproveInd;
}
}
}
if (batchToApproveInd != batchToApprove.length) revert InvalidPermit2Commands();
PERMIT2.permit(
order.taker_address,
IPermit2.PermitBatch(batchToApprove, address(this), infoPermit2.deadline),
infoPermit2.signatureBytes
);
}
}
文件 6 的 20:BytesLib.sol
pragma solidity ^0.8.0;
library BytesLib {
function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
tempBytes := mload(0x40)
let lengthmod := and(_length, 31)
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
mstore(0x40, and(add(mc, 31), not(31)))
}
default {
tempBytes := mload(0x40)
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
}
文件 7 的 20:Commands.sol
pragma solidity ^0.8.0;
library Commands {
bytes1 internal constant SIMPLE_TRANSFER = 0x00;
bytes1 internal constant PERMIT2_TRANSFER = 0x01;
bytes1 internal constant CALL_PERMIT_THEN_TRANSFER = 0x02;
bytes1 internal constant CALL_PERMIT2_THEN_TRANSFER = 0x03;
bytes1 internal constant NATIVE_TRANSFER = 0x04;
bytes1 internal constant TRANSFER_TO_CONTRACT = 0x07;
bytes1 internal constant TRANSFER_FROM_CONTRACT = 0x08;
}
文件 8 的 20:Errors.sol
pragma solidity ^0.8.0;
error OrderInvalidSigner();
error InvalidEIP721Signature();
error InvalidEIP1271Signature();
error InvalidETHSIGNSignature();
error InvalidSignatureType();
error InvalidSignatureLength();
error InvalidSignatureValueS();
error InvalidSignatureValueV();
error ZeroNonce();
error InvalidNonce();
error OrderExpired();
error OrdersLengthsMismatch();
error TokensLengthsMismatch();
error CommandsLengthsMismatch();
error InvalidPermit2Commands();
error InvalidCommand();
error InvalidCommandsLength();
error InvalidFlags();
error PartialFillNotSupported();
error UpdatedMakerAmountsTooLow();
error ZeroMakerAmount();
error MakerAmountsLengthsMismatch();
error NotEnoughNativeToken();
error WrongWrappedTokenAddress();
error FailedToSendNativeToken();
error InvalidSender();
error ManyToManyNotSupported();
error InvalidPendingTransfersLength();
error InvalidPermit2TransfersLength();
error PartnerAlreadyRegistered();
error PartnerFeeTooHigh();
error NullBeneficiary();
文件 9 的 20:IBebopSettlement.sol
pragma solidity ^0.8.0;
import "../libs/Order.sol";
import "../libs/Signature.sol";
import "../libs/Transfer.sol";
interface IBebopSettlement {
event BebopOrder(uint128 indexed eventId);
function swapSingle(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount
) external payable;
function swapSingleFromContract(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature
) external payable;
function settleSingle(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldSingleQuote calldata takerQuoteInfo,
bytes calldata takerSignature
) external payable;
function settleSingleAndSignPermit(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldSingleQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.PermitSignature calldata takerPermitSignature
) external payable;
function settleSingleAndSignPermit2(
Order.Single calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldSingleQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.Permit2Signature calldata takerPermit2Signature
) external payable;
function swapMulti(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount
) external payable;
function settleMulti(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldMultiQuote calldata takerQuoteInfo,
bytes calldata takerSignature
) external payable;
function settleMultiAndSignPermit(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldMultiQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.PermitSignature calldata takerPermitSignature
) external payable;
function settleMultiAndSignPermit2(
Order.Multi calldata order,
Signature.MakerSignature calldata makerSignature,
uint256 filledTakerAmount,
Transfer.OldMultiQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.MultiTokensPermit2Signature calldata infoPermit2
) external payable;
function swapAggregate(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount
) external payable;
function settleAggregate(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
Transfer.OldAggregateQuote calldata takerQuoteInfo,
bytes calldata takerSignature
) external payable;
function settleAggregateAndSignPermit(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
Transfer.OldAggregateQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.PermitSignature calldata takerPermitSignature
) external payable;
function settleAggregateAndSignPermit2(
Order.Aggregate calldata order,
Signature.MakerSignature[] calldata makersSignatures,
uint256 filledTakerAmount,
Transfer.OldAggregateQuote calldata takerQuoteInfo,
bytes calldata takerSignature,
Signature.MultiTokensPermit2Signature calldata infoPermit2
) external payable;
}
文件 10 的 20:IDaiLikePermit.sol
pragma solidity ^0.8.0;
interface IDaiLikePermit {
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external;
function getNonce(address user) external view returns (uint256 nonce);
}
文件 11 的 20:IERC1271.sol
pragma solidity ^0.8.0;
interface IERC1271 {
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
文件 12 的 20:IERC20.sol
pragma solidity ^0.8.0;
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 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 13 的 20:IPermit2.sol
pragma solidity ^0.8.0;
interface IPermit2 {
struct AllowanceTransferDetails {
address from;
address to;
uint160 amount;
address token;
}
struct PermitDetails {
address token;
uint160 amount;
uint48 expiration;
uint48 nonce;
}
struct PermitBatch {
PermitDetails[] details;
address spender;
uint256 sigDeadline;
}
function allowance(address user, address token, address spender)
external
view
returns (uint160 amount, uint48 expiration, uint48 nonce);
function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;
function transferFrom(address from, address to, uint160 amount, address token) external;
function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;
}
文件 14 的 20:IWETH.sol
pragma solidity ^0.8.0;
interface IWETH {
function deposit() external payable;
function withdraw(uint256 amount) external;
}
文件 15 的 20:Order.sol
pragma solidity ^0.8.0;
import "./Signature.sol";
import "../base/Errors.sol";
library Order {
struct Single {
uint256 expiry;
address taker_address;
address maker_address;
uint256 maker_nonce;
address taker_token;
address maker_token;
uint256 taker_amount;
uint256 maker_amount;
address receiver;
uint256 packed_commands;
uint256 flags;
}
struct Multi {
uint256 expiry;
address taker_address;
address maker_address;
uint256 maker_nonce;
address[] taker_tokens;
address[] maker_tokens;
uint256[] taker_amounts;
uint256[] maker_amounts;
address receiver;
bytes commands;
uint256 flags;
}
struct Aggregate {
uint256 expiry;
address taker_address;
address[] maker_addresses;
uint256[] maker_nonces;
address[][] taker_tokens;
address[][] maker_tokens;
uint256[][] taker_amounts;
uint256[][] maker_amounts;
address receiver;
bytes commands;
uint256 flags;
}
function extractSingleOrderCommands(
uint256 commands
) internal pure returns (bool takerHasNative, bool makerHasNative, bool takerUsingPermit2){
takerHasNative = (commands & 0x01) != 0;
makerHasNative = (commands & 0x02) != 0;
takerUsingPermit2 = (commands & 0x04) != 0;
if (takerHasNative && takerUsingPermit2){
revert InvalidFlags();
}
}
function extractSignatureType(uint256 flags) internal pure returns (Signature.Type signatureType){
signatureType = Signature.Type(flags & 0x03);
}
function extractFlags(uint256 flags) internal pure returns (uint128 eventId, uint64 partnerId){
eventId = uint128(flags >> 128);
partnerId = uint64(flags >> 64);
}
function extractPartnerId(uint256 flags) internal pure returns (uint64 partnerId){
partnerId = uint64(flags >> 64);
}
function extractEventId(uint256 flags) internal pure returns (uint128 eventId){
eventId = uint128(flags >> 128);
}
}
文件 16 的 20:SafeCast160.sol
pragma solidity ^0.8.0;
library SafeCast160 {
error UnsafeCast();
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) revert UnsafeCast();
return uint160(value);
}
}
文件 17 的 20:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../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 safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
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");
}
}
}
文件 18 的 20:Signature.sol
pragma solidity ^0.8.0;
import "../base/Errors.sol";
library Signature {
enum Type {
EIP712,
EIP1271,
ETHSIGN
}
struct PermitSignature {
bytes signatureBytes;
uint256 deadline;
}
struct Permit2Signature {
bytes signatureBytes;
uint48 deadline;
uint48 nonce;
}
struct MultiTokensPermit2Signature {
bytes signatureBytes;
uint48 deadline;
uint48[] nonces;
}
struct MakerSignature {
bytes signatureBytes;
uint256 flags;
}
function extractMakerFlags(uint256 flags) internal pure returns (bool usingPermit2, Type signatureType){
signatureType = Type(flags & 0x03);
usingPermit2 = (flags & 0x04) != 0;
}
function getRsv(bytes calldata sig) internal pure returns (bytes32, bytes32, uint8){
if(sig.length != 65) revert InvalidSignatureLength();
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := calldataload(sig.offset)
s := calldataload(add(sig.offset, 32))
v := calldataload(add(sig.offset, 33))
}
if (v < 27) v += 27;
if(uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) revert InvalidSignatureValueS();
if(v != 27 && v != 28) revert InvalidSignatureValueV();
return (r, s, v);
}
}
文件 19 的 20:Transfer.sol
pragma solidity ^0.8.0;
library Transfer {
struct OldSingleQuote {
bool useOldAmount;
uint256 makerAmount;
uint256 makerNonce;
}
struct OldMultiQuote {
bool useOldAmount;
uint256[] makerAmounts;
uint256 makerNonce;
}
struct OldAggregateQuote {
bool useOldAmount;
uint256[][] makerAmounts;
uint256[] makerNonces;
}
enum Action {
None,
Wrap,
Unwrap
}
struct Pending {
address token;
address to;
uint256 amount;
}
struct NativeTokens {
uint256 toTaker;
uint256 toMakers;
}
struct LengthsInfo {
uint48 pendingTransfersLen;
uint48 permit2Len;
}
struct IndicesInfo {
uint48 pendingTransfersInd;
uint48 permit2Ind;
uint256 commandsInd;
}
}
文件 20 的 20:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
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);
}
{
"compilationTarget": {
"src/BebopSettlement.sol": "BebopSettlement"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 77
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"_wrappedNativeToken","type":"address"},{"internalType":"address","name":"_permit2","type":"address"},{"internalType":"address","name":"_daiAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CommandsLengthsMismatch","type":"error"},{"inputs":[],"name":"FailedToSendNativeToken","type":"error"},{"inputs":[],"name":"InvalidCommand","type":"error"},{"inputs":[],"name":"InvalidCommandsLength","type":"error"},{"inputs":[],"name":"InvalidEIP1271Signature","type":"error"},{"inputs":[],"name":"InvalidEIP721Signature","type":"error"},{"inputs":[],"name":"InvalidETHSIGNSignature","type":"error"},{"inputs":[],"name":"InvalidFlags","type":"error"},{"inputs":[],"name":"InvalidNonce","type":"error"},{"inputs":[],"name":"InvalidPendingTransfersLength","type":"error"},{"inputs":[],"name":"InvalidPermit2Commands","type":"error"},{"inputs":[],"name":"InvalidPermit2TransfersLength","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidSignatureLength","type":"error"},{"inputs":[],"name":"InvalidSignatureType","type":"error"},{"inputs":[],"name":"InvalidSignatureValueS","type":"error"},{"inputs":[],"name":"InvalidSignatureValueV","type":"error"},{"inputs":[],"name":"MakerAmountsLengthsMismatch","type":"error"},{"inputs":[],"name":"ManyToManyNotSupported","type":"error"},{"inputs":[],"name":"NotEnoughNativeToken","type":"error"},{"inputs":[],"name":"NullBeneficiary","type":"error"},{"inputs":[],"name":"OrderExpired","type":"error"},{"inputs":[],"name":"OrderInvalidSigner","type":"error"},{"inputs":[],"name":"OrdersLengthsMismatch","type":"error"},{"inputs":[],"name":"PartialFillNotSupported","type":"error"},{"inputs":[],"name":"PartnerAlreadyRegistered","type":"error"},{"inputs":[],"name":"PartnerFeeTooHigh","type":"error"},{"inputs":[],"name":"TokensLengthsMismatch","type":"error"},{"inputs":[],"name":"UnsafeCast","type":"error"},{"inputs":[],"name":"UpdatedMakerAmountsTooLow","type":"error"},{"inputs":[],"name":"WrongWrappedTokenAddress","type":"error"},{"inputs":[],"name":"ZeroMakerAmount","type":"error"},{"inputs":[],"name":"ZeroNonce","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint128","name":"eventId","type":"uint128"}],"name":"BebopOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"maker","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"OrderSignerRegistered","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address[]","name":"maker_addresses","type":"address[]"},{"internalType":"uint256[]","name":"maker_nonces","type":"uint256[]"},{"internalType":"address[][]","name":"taker_tokens","type":"address[][]"},{"internalType":"address[][]","name":"maker_tokens","type":"address[][]"},{"internalType":"uint256[][]","name":"taker_amounts","type":"uint256[][]"},{"internalType":"uint256[][]","name":"maker_amounts","type":"uint256[][]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Aggregate","name":"order","type":"tuple"},{"internalType":"uint64","name":"partnerId","type":"uint64"},{"internalType":"uint256[][]","name":"updatedMakerAmounts","type":"uint256[][]"},{"internalType":"uint256[]","name":"updatedMakerNonces","type":"uint256[]"}],"name":"hashAggregateOrder","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address[]","name":"taker_tokens","type":"address[]"},{"internalType":"address[]","name":"maker_tokens","type":"address[]"},{"internalType":"uint256[]","name":"taker_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maker_amounts","type":"uint256[]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Multi","name":"order","type":"tuple"},{"internalType":"uint64","name":"partnerId","type":"uint64"},{"internalType":"uint256[]","name":"updatedMakerAmounts","type":"uint256[]"},{"internalType":"uint256","name":"updatedMakerNonce","type":"uint256"}],"name":"hashMultiOrder","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address","name":"taker_token","type":"address"},{"internalType":"address","name":"maker_token","type":"address"},{"internalType":"uint256","name":"taker_amount","type":"uint256"},{"internalType":"uint256","name":"maker_amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"packed_commands","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Single","name":"order","type":"tuple"},{"internalType":"uint64","name":"partnerId","type":"uint64"},{"internalType":"uint256","name":"updatedMakerAmount","type":"uint256"},{"internalType":"uint256","name":"updatedMakerNonce","type":"uint256"}],"name":"hashSingleOrder","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"partners","outputs":[{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"bool","name":"registered","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"registerAllowedOrderSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"partnerId","type":"uint64"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"registerPartner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address[]","name":"maker_addresses","type":"address[]"},{"internalType":"uint256[]","name":"maker_nonces","type":"uint256[]"},{"internalType":"address[][]","name":"taker_tokens","type":"address[][]"},{"internalType":"address[][]","name":"maker_tokens","type":"address[][]"},{"internalType":"uint256[][]","name":"taker_amounts","type":"uint256[][]"},{"internalType":"uint256[][]","name":"maker_amounts","type":"uint256[][]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Aggregate","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature[]","name":"makersSignatures","type":"tuple[]"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256[][]","name":"makerAmounts","type":"uint256[][]"},{"internalType":"uint256[]","name":"makerNonces","type":"uint256[]"}],"internalType":"struct Transfer.OldAggregateQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"}],"name":"settleAggregate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address[]","name":"maker_addresses","type":"address[]"},{"internalType":"uint256[]","name":"maker_nonces","type":"uint256[]"},{"internalType":"address[][]","name":"taker_tokens","type":"address[][]"},{"internalType":"address[][]","name":"maker_tokens","type":"address[][]"},{"internalType":"uint256[][]","name":"taker_amounts","type":"uint256[][]"},{"internalType":"uint256[][]","name":"maker_amounts","type":"uint256[][]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Aggregate","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature[]","name":"makersSignatures","type":"tuple[]"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256[][]","name":"makerAmounts","type":"uint256[][]"},{"internalType":"uint256[]","name":"makerNonces","type":"uint256[]"}],"internalType":"struct Transfer.OldAggregateQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Signature.PermitSignature","name":"takerPermitSignature","type":"tuple"}],"name":"settleAggregateAndSignPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address[]","name":"maker_addresses","type":"address[]"},{"internalType":"uint256[]","name":"maker_nonces","type":"uint256[]"},{"internalType":"address[][]","name":"taker_tokens","type":"address[][]"},{"internalType":"address[][]","name":"maker_tokens","type":"address[][]"},{"internalType":"uint256[][]","name":"taker_amounts","type":"uint256[][]"},{"internalType":"uint256[][]","name":"maker_amounts","type":"uint256[][]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Aggregate","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature[]","name":"makersSignatures","type":"tuple[]"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256[][]","name":"makerAmounts","type":"uint256[][]"},{"internalType":"uint256[]","name":"makerNonces","type":"uint256[]"}],"internalType":"struct Transfer.OldAggregateQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint48","name":"deadline","type":"uint48"},{"internalType":"uint48[]","name":"nonces","type":"uint48[]"}],"internalType":"struct Signature.MultiTokensPermit2Signature","name":"infoPermit2","type":"tuple"}],"name":"settleAggregateAndSignPermit2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address[]","name":"taker_tokens","type":"address[]"},{"internalType":"address[]","name":"maker_tokens","type":"address[]"},{"internalType":"uint256[]","name":"taker_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maker_amounts","type":"uint256[]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Multi","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256[]","name":"makerAmounts","type":"uint256[]"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"internalType":"struct Transfer.OldMultiQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"}],"name":"settleMulti","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address[]","name":"taker_tokens","type":"address[]"},{"internalType":"address[]","name":"maker_tokens","type":"address[]"},{"internalType":"uint256[]","name":"taker_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maker_amounts","type":"uint256[]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Multi","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256[]","name":"makerAmounts","type":"uint256[]"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"internalType":"struct Transfer.OldMultiQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Signature.PermitSignature","name":"takerPermitSignature","type":"tuple"}],"name":"settleMultiAndSignPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address[]","name":"taker_tokens","type":"address[]"},{"internalType":"address[]","name":"maker_tokens","type":"address[]"},{"internalType":"uint256[]","name":"taker_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maker_amounts","type":"uint256[]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Multi","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256[]","name":"makerAmounts","type":"uint256[]"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"internalType":"struct Transfer.OldMultiQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint48","name":"deadline","type":"uint48"},{"internalType":"uint48[]","name":"nonces","type":"uint48[]"}],"internalType":"struct Signature.MultiTokensPermit2Signature","name":"infoPermit2","type":"tuple"}],"name":"settleMultiAndSignPermit2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address","name":"taker_token","type":"address"},{"internalType":"address","name":"maker_token","type":"address"},{"internalType":"uint256","name":"taker_amount","type":"uint256"},{"internalType":"uint256","name":"maker_amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"packed_commands","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Single","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256","name":"makerAmount","type":"uint256"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"internalType":"struct Transfer.OldSingleQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"}],"name":"settleSingle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address","name":"taker_token","type":"address"},{"internalType":"address","name":"maker_token","type":"address"},{"internalType":"uint256","name":"taker_amount","type":"uint256"},{"internalType":"uint256","name":"maker_amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"packed_commands","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Single","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256","name":"makerAmount","type":"uint256"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"internalType":"struct Transfer.OldSingleQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Signature.PermitSignature","name":"takerPermitSignature","type":"tuple"}],"name":"settleSingleAndSignPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address","name":"taker_token","type":"address"},{"internalType":"address","name":"maker_token","type":"address"},{"internalType":"uint256","name":"taker_amount","type":"uint256"},{"internalType":"uint256","name":"maker_amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"packed_commands","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Single","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"},{"components":[{"internalType":"bool","name":"useOldAmount","type":"bool"},{"internalType":"uint256","name":"makerAmount","type":"uint256"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"internalType":"struct Transfer.OldSingleQuote","name":"takerQuoteInfo","type":"tuple"},{"internalType":"bytes","name":"takerSignature","type":"bytes"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint48","name":"deadline","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"internalType":"struct Signature.Permit2Signature","name":"takerPermit2Signature","type":"tuple"}],"name":"settleSingleAndSignPermit2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address[]","name":"maker_addresses","type":"address[]"},{"internalType":"uint256[]","name":"maker_nonces","type":"uint256[]"},{"internalType":"address[][]","name":"taker_tokens","type":"address[][]"},{"internalType":"address[][]","name":"maker_tokens","type":"address[][]"},{"internalType":"uint256[][]","name":"taker_amounts","type":"uint256[][]"},{"internalType":"uint256[][]","name":"maker_amounts","type":"uint256[][]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Aggregate","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature[]","name":"makersSignatures","type":"tuple[]"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"}],"name":"swapAggregate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address[]","name":"taker_tokens","type":"address[]"},{"internalType":"address[]","name":"maker_tokens","type":"address[]"},{"internalType":"uint256[]","name":"taker_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maker_amounts","type":"uint256[]"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Multi","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"}],"name":"swapMulti","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address","name":"taker_token","type":"address"},{"internalType":"address","name":"maker_token","type":"address"},{"internalType":"uint256","name":"taker_amount","type":"uint256"},{"internalType":"uint256","name":"maker_amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"packed_commands","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Single","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"},{"internalType":"uint256","name":"filledTakerAmount","type":"uint256"}],"name":"swapSingle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"taker_address","type":"address"},{"internalType":"address","name":"maker_address","type":"address"},{"internalType":"uint256","name":"maker_nonce","type":"uint256"},{"internalType":"address","name":"taker_token","type":"address"},{"internalType":"address","name":"maker_token","type":"address"},{"internalType":"uint256","name":"taker_amount","type":"uint256"},{"internalType":"uint256","name":"maker_amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"packed_commands","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Order.Single","name":"order","type":"tuple"},{"components":[{"internalType":"bytes","name":"signatureBytes","type":"bytes"},{"internalType":"uint256","name":"flags","type":"uint256"}],"internalType":"struct Signature.MakerSignature","name":"makerSignature","type":"tuple"}],"name":"swapSingleFromContract","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]