Update ExchangeProxySwapQuoteConsumer for MultiplexV2 (#282)

* Update ExchangeProxySwapQuoteConsumer for MultiplexV2

* Move TransformERC20FeatureContract instance into private readonly
This commit is contained in:
mzhu25 2021-09-29 16:02:13 -07:00 committed by GitHub
parent a883139220
commit 1849b1bb9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 2130 additions and 490 deletions

View File

@ -1,4 +1,13 @@
[
{
"version": "0.29.0",
"changes": [
{
"note": "Export TransformERC20FeatureContract",
"pr": 282
}
]
},
{
"timestamp": 1631710679,
"version": "0.28.5",

View File

@ -47,6 +47,7 @@ export {
MultiplexFeatureContract,
PayTakerTransformerContract,
PositiveSlippageFeeTransformerContract,
TransformERC20FeatureContract,
WethTransformerContract,
ZeroExContract,
} from './wrappers';

View File

@ -1,4 +1,13 @@
[
{
"version": "16.28.0",
"changes": [
{
"note": "Update ExchangeProxySwapQuoteConsumer for Multiplex V2 and friends",
"pr": 282
}
]
},
{
"version": "16.27.5",
"changes": [

View File

@ -63,7 +63,7 @@
"@0x/contract-addresses": "^6.7.0",
"@0x/contract-wrappers": "^13.17.7",
"@0x/contracts-erc20": "^3.3.20",
"@0x/contracts-zero-ex": "^0.27.1",
"@0x/contracts-zero-ex": "^0.28.4",
"@0x/dev-utils": "^4.2.9",
"@0x/json-schemas": "^6.3.0",
"@0x/protocol-utils": "^1.9.0",

View File

@ -1,6 +1,6 @@
import { ChainId, ContractAddresses } from '@0x/contract-addresses';
import { IZeroExContract, WETH9Contract } from '@0x/contract-wrappers';
import { MultiplexFeatureContract } from '@0x/contracts-zero-ex';
import { IZeroExContract } from '@0x/contract-wrappers';
import { TransformERC20FeatureContract } from '@0x/contracts-zero-ex';
import {
encodeAffiliateFeeTransformerData,
encodeCurveLiquidityProviderData,
@ -51,6 +51,7 @@ import {
import {
multiplexPlpEncoder,
multiplexRfqEncoder,
MultiplexSubcall,
multiplexTransformERC20Encoder,
multiplexUniswapEncoder,
} from './multiplex_encoders';
@ -82,7 +83,6 @@ const FAKE_PROVIDER: any = {
return;
},
};
const DUMMY_WETH_CONTRACT = new WETH9Contract(NULL_ADDRESS, FAKE_PROVIDER);
export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
public readonly chainId: ChainId;
@ -95,7 +95,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
};
private readonly _exchangeProxy: IZeroExContract;
private readonly _multiplex: MultiplexFeatureContract;
private readonly _transformERC20Feature: TransformERC20FeatureContract;
constructor(public readonly contractAddresses: ContractAddresses, options: Partial<SwapQuoteConsumerOpts> = {}) {
const { chainId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
@ -103,7 +103,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
this.chainId = chainId;
this.contractAddresses = contractAddresses;
this._exchangeProxy = new IZeroExContract(contractAddresses.exchangeProxy, FAKE_PROVIDER);
this._multiplex = new MultiplexFeatureContract(contractAddresses.exchangeProxy, FAKE_PROVIDER);
this._transformERC20Feature = new TransformERC20FeatureContract(contractAddresses.exchangeProxy, FAKE_PROVIDER);
this.transformerNonces = {
wethTransformer: findTransformerNonce(
contractAddresses.transformers.wethTransformer,
@ -338,7 +338,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
return {
calldataHexString: this._encodeMultiplexBatchFillCalldata({ ...quote, orders: slippedOrders }),
calldataHexString: this._encodeMultiplexBatchFillCalldata(
{ ...quote, orders: slippedOrders },
optsWithDefaults,
),
ethAmount,
toAddress: this._exchangeProxy.address,
allowanceTarget: this._exchangeProxy.address,
@ -473,17 +476,27 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
}
}
// Return any unspent sell tokens.
const payTakerTokens = [sellToken];
// Return any unspent intermediate tokens for two-hop swaps.
if (quote.isTwoHop) {
payTakerTokens.push(intermediateToken);
}
// Return any unspent ETH. If ETH is the buy token, it will
// be returned in TransformERC20Feature rather than PayTakerTransformer.
if (!isToETH) {
payTakerTokens.push(ETH_TOKEN_ADDRESS);
}
// The final transformer will send all funds to the taker.
transforms.push({
deploymentNonce: this.transformerNonces.payTakerTransformer,
data: encodePayTakerTransformerData({
tokens: [sellToken, buyToken, ETH_TOKEN_ADDRESS].concat(quote.isTwoHop ? intermediateToken : []),
tokens: payTakerTokens,
amounts: [],
}),
});
const calldataHexString = this._exchangeProxy
.transformERC20(
const calldataHexString = this._transformERC20Feature
.transformERC20Staging(
isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
isToETH ? ETH_TOKEN_ADDRESS : buyToken,
shouldSellEntireBalance ? MAX_UINT256 : sellAmount,
@ -509,8 +522,8 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
throw new Error('Execution not supported for Exchange Proxy quotes');
}
private _encodeMultiplexBatchFillCalldata(quote: SwapQuote): string {
const wrappedBatchCalls = [];
private _encodeMultiplexBatchFillCalldata(quote: SwapQuote, opts: ExchangeProxyContractOpts): string {
const subcalls = [];
for_loop: for (const [i, order] of quote.orders.entries()) {
switch_statement: switch (order.source) {
case ERC20BridgeSource.Native:
@ -519,8 +532,8 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
// before calling this function.
throw new Error('Multiplex batch fill only supported for RFQ native orders');
}
wrappedBatchCalls.push({
selector: this._exchangeProxy.getSelector('_fillRfqOrder'),
subcalls.push({
id: MultiplexSubcall.Rfq,
sellAmount: order.takerAmount,
data: multiplexRfqEncoder.encode({
order: order.fillData.order,
@ -530,8 +543,8 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
break switch_statement;
case ERC20BridgeSource.UniswapV2:
case ERC20BridgeSource.SushiSwap:
wrappedBatchCalls.push({
selector: this._multiplex.getSelector('_sellToUniswap'),
subcalls.push({
id: MultiplexSubcall.UniswapV2,
sellAmount: order.takerAmount,
data: multiplexUniswapEncoder.encode({
tokens: (order.fillData as UniswapV2FillData).tokenAddressPath,
@ -540,8 +553,8 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
});
break switch_statement;
case ERC20BridgeSource.LiquidityProvider:
wrappedBatchCalls.push({
selector: this._multiplex.getSelector('_sellToLiquidityProvider'),
subcalls.push({
id: MultiplexSubcall.LiquidityProvider,
sellAmount: order.takerAmount,
data: multiplexPlpEncoder.encode({
provider: (order.fillData as LiquidityProviderFillData).poolAddress,
@ -551,8 +564,8 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
break switch_statement;
case ERC20BridgeSource.UniswapV3:
const fillData = (order as OptimizedMarketBridgeOrder<FinalUniswapV3FillData>).fillData;
wrappedBatchCalls.push({
selector: this._exchangeProxy.getSelector('sellTokenForTokenToUniswapV3'),
subcalls.push({
id: MultiplexSubcall.UniswapV3,
sellAmount: order.takerAmount,
data: fillData.uniswapPath,
});
@ -571,54 +584,59 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
{
deploymentNonce: this.transformerNonces.payTakerTransformer,
data: encodePayTakerTransformerData({
tokens: [quote.takerToken, quote.makerToken],
tokens: [quote.takerToken],
amounts: [],
}),
},
];
wrappedBatchCalls.push({
selector: this._exchangeProxy.getSelector('_transformERC20'),
subcalls.push({
id: MultiplexSubcall.TransformERC20,
sellAmount: BigNumber.sum(...quote.orders.slice(i).map(o => o.takerAmount)),
data: multiplexTransformERC20Encoder.encode({
transformations,
ethValue: constants.ZERO_AMOUNT,
}),
});
break for_loop;
}
}
if (opts.isFromETH) {
return this._exchangeProxy
.batchFill(
{
inputToken: quote.takerToken,
outputToken: quote.makerToken,
sellAmount: quote.worstCaseQuoteInfo.totalTakerAmount,
calls: wrappedBatchCalls,
},
.multiplexBatchSellEthForToken(quote.makerToken, subcalls, quote.worstCaseQuoteInfo.makerAmount)
.getABIEncodedTransactionData();
} else if (opts.isToETH) {
return this._exchangeProxy
.multiplexBatchSellTokenForEth(
quote.takerToken,
subcalls,
quote.worstCaseQuoteInfo.totalTakerAmount,
quote.worstCaseQuoteInfo.makerAmount,
)
.getABIEncodedTransactionData();
} else {
return this._exchangeProxy
.multiplexBatchSellTokenForToken(
quote.takerToken,
quote.makerToken,
subcalls,
quote.worstCaseQuoteInfo.totalTakerAmount,
quote.worstCaseQuoteInfo.makerAmount,
)
.getABIEncodedTransactionData();
}
}
private _encodeMultiplexMultiHopFillCalldata(quote: SwapQuote, opts: ExchangeProxyContractOpts): string {
const wrappedMultiHopCalls = [];
const tokens: string[] = [];
if (opts.isFromETH) {
wrappedMultiHopCalls.push({
selector: DUMMY_WETH_CONTRACT.getSelector('deposit'),
data: NULL_BYTES,
});
tokens.push(ETH_TOKEN_ADDRESS);
}
const subcalls = [];
const [firstHopOrder, secondHopOrder] = quote.orders;
const intermediateToken = firstHopOrder.makerToken;
tokens.push(quote.takerToken, intermediateToken, quote.makerToken);
const tokens = [quote.takerToken, intermediateToken, quote.makerToken];
for (const order of [firstHopOrder, secondHopOrder]) {
switch (order.source) {
case ERC20BridgeSource.UniswapV2:
case ERC20BridgeSource.SushiSwap:
wrappedMultiHopCalls.push({
selector: this._multiplex.getSelector('_sellToUniswap'),
subcalls.push({
id: MultiplexSubcall.UniswapV2,
data: multiplexUniswapEncoder.encode({
tokens: (order.fillData as UniswapV2FillData).tokenAddressPath,
isSushi: order.source === ERC20BridgeSource.SushiSwap,
@ -626,39 +644,49 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
});
break;
case ERC20BridgeSource.LiquidityProvider:
wrappedMultiHopCalls.push({
selector: this._multiplex.getSelector('_sellToLiquidityProvider'),
subcalls.push({
id: MultiplexSubcall.LiquidityProvider,
data: multiplexPlpEncoder.encode({
provider: (order.fillData as LiquidityProviderFillData).poolAddress,
auxiliaryData: NULL_BYTES,
}),
});
break;
case ERC20BridgeSource.UniswapV3:
subcalls.push({
id: MultiplexSubcall.UniswapV3,
data: (order.fillData as FinalUniswapV3FillData).uniswapPath,
});
break;
default:
// Note: we'll need to redeploy TransformERC20Feature before we can
// use other sources
// Should never happen because we check `isMultiplexMultiHopFillCompatible`
// before calling this function.
throw new Error(`Multiplex multi-hop unsupported source: ${order.source}`);
}
}
if (opts.isToETH) {
wrappedMultiHopCalls.push({
selector: DUMMY_WETH_CONTRACT.getSelector('withdraw'),
data: NULL_BYTES,
});
tokens.push(ETH_TOKEN_ADDRESS);
}
if (opts.isFromETH) {
return this._exchangeProxy
.multiHopFill(
{
.multiplexMultiHopSellEthForToken(tokens, subcalls, quote.worstCaseQuoteInfo.makerAmount)
.getABIEncodedTransactionData();
} else if (opts.isToETH) {
return this._exchangeProxy
.multiplexMultiHopSellTokenForEth(
tokens,
sellAmount: quote.worstCaseQuoteInfo.totalTakerAmount,
calls: wrappedMultiHopCalls,
},
subcalls,
quote.worstCaseQuoteInfo.totalTakerAmount,
quote.worstCaseQuoteInfo.makerAmount,
)
.getABIEncodedTransactionData();
} else {
return this._exchangeProxy
.multiplexMultiHopSellTokenForToken(
tokens,
subcalls,
quote.worstCaseQuoteInfo.totalTakerAmount,
quote.worstCaseQuoteInfo.makerAmount,
)
.getABIEncodedTransactionData();
}
}
}

View File

@ -1,6 +1,17 @@
import { RfqOrder, SIGNATURE_ABI } from '@0x/protocol-utils';
import { AbiEncoder } from '@0x/utils';
export enum MultiplexSubcall {
Invalid,
Rfq,
Otc,
UniswapV2,
UniswapV3,
LiquidityProvider,
TransformERC20,
BatchSell,
MultiHopSell,
}
export const multiplexTransformERC20Encoder = AbiEncoder.create([
{
name: 'transformations',
@ -10,7 +21,6 @@ export const multiplexTransformERC20Encoder = AbiEncoder.create([
{ name: 'data', type: 'bytes' },
],
},
{ name: 'ethValue', type: 'uint256' },
]);
export const multiplexRfqEncoder = AbiEncoder.create([
{ name: 'order', type: 'tuple', components: RfqOrder.STRUCT_ABI },

View File

@ -32,10 +32,6 @@ export function isMultiplexBatchFillCompatible(quote: SwapQuote, opts: ExchangeP
if (quote.isTwoHop) {
return false;
}
// batchFill does not support WETH wrapping/unwrapping at the moment
if (opts.isFromETH || opts.isToETH) {
return false;
}
if (quote.orders.map(o => o.type).includes(FillQuoteTransformerOrderType.Limit)) {
return false;
}
@ -49,6 +45,7 @@ const MULTIPLEX_MULTIHOP_FILL_SOURCES = [
ERC20BridgeSource.UniswapV2,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.LiquidityProvider,
ERC20BridgeSource.UniswapV3,
];
/**

View File

@ -186,7 +186,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
);
}
const transformERC20Encoder = AbiEncoder.createMethod('transformERC20', [
const transformERC20Encoder = AbiEncoder.createMethod('transformERC20Staging', [
{ type: 'address', name: 'inputToken' },
{ type: 'address', name: 'outputToken' },
{ type: 'uint256', name: 'inputTokenAmount' },
@ -261,7 +261,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
expect(fillQuoteTransformerData.buyToken).to.eq(MAKER_TOKEN);
const payTakerTransformerData = decodePayTakerTransformerData(callArgs.transformations[1].data);
expect(payTakerTransformerData.amounts).to.deep.eq([]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, MAKER_TOKEN, ETH_TOKEN_ADDRESS]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, ETH_TOKEN_ADDRESS]);
});
it('can produce a buy quote', async () => {
@ -292,7 +292,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
expect(fillQuoteTransformerData.buyToken).to.eq(MAKER_TOKEN);
const payTakerTransformerData = decodePayTakerTransformerData(callArgs.transformations[1].data);
expect(payTakerTransformerData.amounts).to.deep.eq([]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, MAKER_TOKEN, ETH_TOKEN_ADDRESS]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, ETH_TOKEN_ADDRESS]);
});
it('ERC20 -> ERC20 does not have a WETH transformer', async () => {
@ -437,12 +437,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
expect(secondHopFillQuoteTransformerData.buyToken).to.eq(MAKER_TOKEN);
const payTakerTransformerData = decodePayTakerTransformerData(callArgs.transformations[2].data);
expect(payTakerTransformerData.amounts).to.deep.eq([]);
expect(payTakerTransformerData.tokens).to.deep.eq([
TAKER_TOKEN,
MAKER_TOKEN,
ETH_TOKEN_ADDRESS,
INTERMEDIATE_TOKEN,
]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, INTERMEDIATE_TOKEN, ETH_TOKEN_ADDRESS]);
});
// it.skip('Uses the `LiquidityProviderFeature` if given a single LiquidityProvider order', async () => {
// const quote = {
@ -504,7 +499,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
expect(fillQuoteTransformerData.buyToken).to.eq(MAKER_TOKEN);
const payTakerTransformerData = decodePayTakerTransformerData(callArgs.transformations[1].data);
expect(payTakerTransformerData.amounts).to.deep.eq([]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, MAKER_TOKEN, ETH_TOKEN_ADDRESS]);
expect(payTakerTransformerData.tokens).to.deep.eq([TAKER_TOKEN, ETH_TOKEN_ADDRESS]);
});
});
});

View File

@ -1,4 +1,13 @@
[
{
"version": "3.16.0",
"changes": [
{
"note": "Update IZeroEx and ITransformERC20 artifacts",
"pr": 282
}
]
},
{
"timestamp": 1631710679,
"version": "3.15.1",

View File

@ -1,6 +1,6 @@
{
"schemaVersion": "2.0.0",
"contractName": "ITransformERC20",
"contractName": "ITransformERC20Feature",
"compilerOutput": {
"abi": [
{
@ -43,14 +43,14 @@
{ "internalType": "uint32", "name": "deploymentNonce", "type": "uint32" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct ITransformERC20.Transformation[]",
"internalType": "struct ITransformERC20Feature.Transformation[]",
"name": "transformations",
"type": "tuple[]"
},
{ "internalType": "bytes32", "name": "callDataHash", "type": "bytes32" },
{ "internalType": "bytes", "name": "callDataSignature", "type": "bytes" }
{ "internalType": "bool", "name": "useSelfBalance", "type": "bool" },
{ "internalType": "address payable", "name": "recipient", "type": "address" }
],
"internalType": "struct ITransformERC20.TransformERC20Args",
"internalType": "struct ITransformERC20Feature.TransformERC20Args",
"name": "args",
"type": "tuple"
}
@ -113,7 +113,7 @@
{ "internalType": "uint32", "name": "deploymentNonce", "type": "uint32" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct ITransformERC20.Transformation[]",
"internalType": "struct ITransformERC20Feature.Transformation[]",
"name": "transformations",
"type": "tuple[]"
}
@ -148,7 +148,7 @@
},
"kind": "dev",
"methods": {
"_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bytes32,bytes))": {
"_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bool,address))": {
"details": "Internal version of `transformERC20()`. Only callable from within.",
"params": { "args": "A `TransformERC20Args` struct." },
"returns": { "outputTokenAmount": "The amount of `outputToken` received by the taker." }
@ -212,7 +212,8 @@
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap"
"evm.deployedBytecode.sourceMap",
"evm.methodIdentifiers"
]
}
},

View File

@ -3,16 +3,6 @@
"contractName": "IZeroEx",
"compilerOutput": {
"abi": [
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "bytes32", "name": "orderHash", "type": "bytes32" },
{ "indexed": false, "internalType": "address", "name": "maker", "type": "address" },
{ "indexed": false, "internalType": "uint64", "name": "expiry", "type": "uint64" }
],
"name": "ExpiredRfqOrder",
"type": "event"
},
{
"anonymous": false,
"inputs": [
@ -49,11 +39,26 @@
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address", "name": "inputToken", "type": "address" },
{ "indexed": false, "internalType": "address", "name": "outputToken", "type": "address" },
{
"indexed": false,
"internalType": "contract IERC20TokenV06",
"name": "inputToken",
"type": "address"
},
{
"indexed": false,
"internalType": "contract IERC20TokenV06",
"name": "outputToken",
"type": "address"
},
{ "indexed": false, "internalType": "uint256", "name": "inputTokenAmount", "type": "uint256" },
{ "indexed": false, "internalType": "uint256", "name": "outputTokenAmount", "type": "uint256" },
{ "indexed": false, "internalType": "address", "name": "provider", "type": "address" },
{
"indexed": false,
"internalType": "contract ILiquidityProvider",
"name": "provider",
"type": "address"
},
{ "indexed": false, "internalType": "address", "name": "recipient", "type": "address" }
],
"name": "LiquidityProviderSwap",
@ -110,10 +115,10 @@
{
"indexed": false,
"internalType": "uint128",
"name": "takerTokenFilledAmount",
"name": "makerTokenFilledAmount",
"type": "uint128"
},
{ "indexed": false, "internalType": "uint128", "name": "makerTokenFilledAmount", "type": "uint128" }
{ "indexed": false, "internalType": "uint128", "name": "takerTokenFilledAmount", "type": "uint128" }
],
"name": "OtcOrderFilled",
"type": "event"
@ -268,6 +273,51 @@
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "contract IERC20TokenV06", "name": "makerToken", "type": "address" },
{ "internalType": "contract IERC20TokenV06", "name": "takerToken", "type": "address" },
{ "internalType": "uint128", "name": "makerAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "takerAmount", "type": "uint128" },
{ "internalType": "address", "name": "maker", "type": "address" },
{ "internalType": "address", "name": "taker", "type": "address" },
{ "internalType": "address", "name": "txOrigin", "type": "address" },
{ "internalType": "uint256", "name": "expiryAndNonce", "type": "uint256" }
],
"internalType": "struct LibNativeOrder.OtcOrder",
"name": "order",
"type": "tuple"
},
{
"components": [
{
"internalType": "enum LibSignature.SignatureType",
"name": "signatureType",
"type": "uint8"
},
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"internalType": "struct LibSignature.Signature",
"name": "makerSignature",
"type": "tuple"
},
{ "internalType": "uint128", "name": "takerTokenFillAmount", "type": "uint128" },
{ "internalType": "address", "name": "taker", "type": "address" },
{ "internalType": "bool", "name": "useSelfBalance", "type": "bool" },
{ "internalType": "address", "name": "recipient", "type": "address" }
],
"name": "_fillOtcOrder",
"outputs": [
{ "internalType": "uint128", "name": "takerTokenFilledAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "makerTokenFilledAmount", "type": "uint128" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
@ -303,7 +353,9 @@
"type": "tuple"
},
{ "internalType": "uint128", "name": "takerTokenFillAmount", "type": "uint128" },
{ "internalType": "address", "name": "taker", "type": "address" }
{ "internalType": "address", "name": "taker", "type": "address" },
{ "internalType": "bool", "name": "useSelfBalance", "type": "bool" },
{ "internalType": "address", "name": "recipient", "type": "address" }
],
"name": "_fillRfqOrder",
"outputs": [
@ -313,6 +365,18 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes", "name": "encodedPath", "type": "bytes" },
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" },
{ "internalType": "address", "name": "recipient", "type": "address" }
],
"name": "_sellHeldTokenForTokenToUniswapV3",
"outputs": [{ "internalType": "uint256", "name": "buyAmount", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
@ -330,7 +394,9 @@
"internalType": "struct ITransformERC20Feature.Transformation[]",
"name": "transformations",
"type": "tuple[]"
}
},
{ "internalType": "bool", "name": "useSelfBalance", "type": "bool" },
{ "internalType": "address payable", "name": "recipient", "type": "address" }
],
"internalType": "struct ITransformERC20Feature.TransformERC20Args",
"name": "args",
@ -480,35 +546,6 @@
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "contract IERC20TokenV06", "name": "inputToken", "type": "address" },
{ "internalType": "contract IERC20TokenV06", "name": "outputToken", "type": "address" },
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{
"components": [
{ "internalType": "bytes4", "name": "selector", "type": "bytes4" },
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.WrappedBatchCall[]",
"name": "calls",
"type": "tuple[]"
}
],
"internalType": "struct IMultiplexFeature.BatchFillData",
"name": "fillData",
"type": "tuple"
},
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "batchFill",
"outputs": [{ "internalType": "uint256", "name": "outputTokenAmount", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
@ -601,6 +638,60 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "contract IERC20TokenV06", "name": "makerToken", "type": "address" },
{ "internalType": "contract IERC20TokenV06", "name": "takerToken", "type": "address" },
{ "internalType": "uint128", "name": "makerAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "takerAmount", "type": "uint128" },
{ "internalType": "address", "name": "maker", "type": "address" },
{ "internalType": "address", "name": "taker", "type": "address" },
{ "internalType": "address", "name": "txOrigin", "type": "address" },
{ "internalType": "uint256", "name": "expiryAndNonce", "type": "uint256" }
],
"internalType": "struct LibNativeOrder.OtcOrder[]",
"name": "orders",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "enum LibSignature.SignatureType",
"name": "signatureType",
"type": "uint8"
},
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"internalType": "struct LibSignature.Signature[]",
"name": "makerSignatures",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "enum LibSignature.SignatureType",
"name": "signatureType",
"type": "uint8"
},
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"internalType": "struct LibSignature.Signature[]",
"name": "takerSignatures",
"type": "tuple[]"
},
{ "internalType": "bool[]", "name": "unwrapWeth", "type": "bool[]" }
],
"name": "batchFillTakerSignedOtcOrders",
"outputs": [{ "internalType": "bool[]", "name": "successes", "type": "bool[]" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
@ -1026,8 +1117,7 @@
"name": "makerSignature",
"type": "tuple"
},
{ "internalType": "uint128", "name": "takerTokenFillAmount", "type": "uint128" },
{ "internalType": "bool", "name": "unwrapWeth", "type": "bool" }
{ "internalType": "uint128", "name": "takerTokenFillAmount", "type": "uint128" }
],
"name": "fillOtcOrder",
"outputs": [
@ -1037,6 +1127,48 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "contract IERC20TokenV06", "name": "makerToken", "type": "address" },
{ "internalType": "contract IERC20TokenV06", "name": "takerToken", "type": "address" },
{ "internalType": "uint128", "name": "makerAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "takerAmount", "type": "uint128" },
{ "internalType": "address", "name": "maker", "type": "address" },
{ "internalType": "address", "name": "taker", "type": "address" },
{ "internalType": "address", "name": "txOrigin", "type": "address" },
{ "internalType": "uint256", "name": "expiryAndNonce", "type": "uint256" }
],
"internalType": "struct LibNativeOrder.OtcOrder",
"name": "order",
"type": "tuple"
},
{
"components": [
{
"internalType": "enum LibSignature.SignatureType",
"name": "signatureType",
"type": "uint8"
},
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"internalType": "struct LibSignature.Signature",
"name": "makerSignature",
"type": "tuple"
},
{ "internalType": "uint128", "name": "takerTokenFillAmount", "type": "uint128" }
],
"name": "fillOtcOrderForEth",
"outputs": [
{ "internalType": "uint128", "name": "takerTokenFilledAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "makerTokenFilledAmount", "type": "uint128" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
@ -1168,14 +1300,63 @@
"internalType": "struct LibSignature.Signature",
"name": "takerSignature",
"type": "tuple"
},
{ "internalType": "bool", "name": "unwrapWeth", "type": "bool" }
}
],
"name": "fillTakerSignedOtcOrder",
"outputs": [
{ "internalType": "uint128", "name": "takerTokenFilledAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "makerTokenFilledAmount", "type": "uint128" }
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "contract IERC20TokenV06", "name": "makerToken", "type": "address" },
{ "internalType": "contract IERC20TokenV06", "name": "takerToken", "type": "address" },
{ "internalType": "uint128", "name": "makerAmount", "type": "uint128" },
{ "internalType": "uint128", "name": "takerAmount", "type": "uint128" },
{ "internalType": "address", "name": "maker", "type": "address" },
{ "internalType": "address", "name": "taker", "type": "address" },
{ "internalType": "address", "name": "txOrigin", "type": "address" },
{ "internalType": "uint256", "name": "expiryAndNonce", "type": "uint256" }
],
"internalType": "struct LibNativeOrder.OtcOrder",
"name": "order",
"type": "tuple"
},
{
"components": [
{
"internalType": "enum LibSignature.SignatureType",
"name": "signatureType",
"type": "uint8"
},
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"internalType": "struct LibSignature.Signature",
"name": "makerSignature",
"type": "tuple"
},
{
"components": [
{
"internalType": "enum LibSignature.SignatureType",
"name": "signatureType",
"type": "uint8"
},
{ "internalType": "uint8", "name": "v", "type": "uint8" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
],
"internalType": "struct LibSignature.Signature",
"name": "takerSignature",
"type": "tuple"
}
],
"name": "fillTakerSignedOtcOrderForEth",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
@ -1604,31 +1785,150 @@
},
{
"inputs": [
{ "internalType": "contract IERC20TokenV06", "name": "outputToken", "type": "address" },
{
"components": [
{ "internalType": "address[]", "name": "tokens", "type": "address[]" },
{
"internalType": "enum IMultiplexFeature.MultiplexSubcall",
"name": "id",
"type": "uint8"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{
"components": [
{ "internalType": "bytes4", "name": "selector", "type": "bytes4" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.WrappedMultiHopCall[]",
"internalType": "struct IMultiplexFeature.BatchSellSubcall[]",
"name": "calls",
"type": "tuple[]"
}
],
"internalType": "struct IMultiplexFeature.MultiHopFillData",
"name": "fillData",
"type": "tuple"
},
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "multiHopFill",
"outputs": [{ "internalType": "uint256", "name": "outputTokenAmount", "type": "uint256" }],
"name": "multiplexBatchSellEthForToken",
"outputs": [{ "internalType": "uint256", "name": "boughtAmount", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "contract IERC20TokenV06", "name": "inputToken", "type": "address" },
{
"components": [
{
"internalType": "enum IMultiplexFeature.MultiplexSubcall",
"name": "id",
"type": "uint8"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.BatchSellSubcall[]",
"name": "calls",
"type": "tuple[]"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "multiplexBatchSellTokenForEth",
"outputs": [{ "internalType": "uint256", "name": "boughtAmount", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "contract IERC20TokenV06", "name": "inputToken", "type": "address" },
{ "internalType": "contract IERC20TokenV06", "name": "outputToken", "type": "address" },
{
"components": [
{
"internalType": "enum IMultiplexFeature.MultiplexSubcall",
"name": "id",
"type": "uint8"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.BatchSellSubcall[]",
"name": "calls",
"type": "tuple[]"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "multiplexBatchSellTokenForToken",
"outputs": [{ "internalType": "uint256", "name": "boughtAmount", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "tokens", "type": "address[]" },
{
"components": [
{
"internalType": "enum IMultiplexFeature.MultiplexSubcall",
"name": "id",
"type": "uint8"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.MultiHopSellSubcall[]",
"name": "calls",
"type": "tuple[]"
},
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "multiplexMultiHopSellEthForToken",
"outputs": [{ "internalType": "uint256", "name": "boughtAmount", "type": "uint256" }],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "tokens", "type": "address[]" },
{
"components": [
{
"internalType": "enum IMultiplexFeature.MultiplexSubcall",
"name": "id",
"type": "uint8"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.MultiHopSellSubcall[]",
"name": "calls",
"type": "tuple[]"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "multiplexMultiHopSellTokenForEth",
"outputs": [{ "internalType": "uint256", "name": "boughtAmount", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "tokens", "type": "address[]" },
{
"components": [
{
"internalType": "enum IMultiplexFeature.MultiplexSubcall",
"name": "id",
"type": "uint8"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"internalType": "struct IMultiplexFeature.MultiHopSellSubcall[]",
"name": "calls",
"type": "tuple[]"
},
{ "internalType": "uint256", "name": "sellAmount", "type": "uint256" },
{ "internalType": "uint256", "name": "minBuyAmount", "type": "uint256" }
],
"name": "multiplexMultiHopSellTokenForToken",
"outputs": [{ "internalType": "uint256", "name": "boughtAmount", "type": "uint256" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
@ -1819,20 +2119,47 @@
"takerTokenFilledAmount": "How much maker token was filled."
}
},
"_fillRfqOrder((address,address,uint128,uint128,address,address,address,bytes32,uint64,uint256),(uint8,uint8,bytes32,bytes32),uint128,address)": {
"_fillOtcOrder((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),uint128,address,bool,address)": {
"details": "Fill an OTC order for up to `takerTokenFillAmount` taker tokens. Internal variant.",
"params": {
"makerSignature": "The order signature from the maker.",
"order": "The OTC order.",
"recipient": "The recipient of the bought maker tokens.",
"taker": "The address to fill the order in the context of.",
"takerTokenFillAmount": "Maximum taker token amount to fill this order with.",
"useSelfBalance": "Whether to use the Exchange Proxy's balance of input tokens."
},
"returns": {
"makerTokenFilledAmount": "How much maker token was filled.",
"takerTokenFilledAmount": "How much taker token was filled."
}
},
"_fillRfqOrder((address,address,uint128,uint128,address,address,address,bytes32,uint64,uint256),(uint8,uint8,bytes32,bytes32),uint128,address,bool,address)": {
"details": "Fill an RFQ order. Internal variant.",
"params": {
"order": "The RFQ order.",
"recipient": "The recipient of the maker tokens.",
"signature": "The order signature.",
"taker": "The order taker.",
"takerTokenFillAmount": "Maximum taker token to fill this order with."
"takerTokenFillAmount": "Maximum taker token to fill this order with.",
"useSelfBalance": "Whether to use the ExchangeProxy's transient balance of taker tokens to fill the order."
},
"returns": {
"makerTokenFilledAmount": "How much maker token was filled.",
"takerTokenFilledAmount": "How much maker token was filled."
}
},
"_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[]))": {
"_sellHeldTokenForTokenToUniswapV3(bytes,uint256,uint256,address)": {
"details": "Sell a token for another token directly against uniswap v3. Private variant, uses tokens held by `address(this)`.",
"params": {
"encodedPath": "Uniswap-encoded path.",
"minBuyAmount": "Minimum amount of the last token in the path to buy.",
"recipient": "The recipient of the bought tokens. Can be zero for sender.",
"sellAmount": "amount of the first token in the path to sell."
},
"returns": { "buyAmount": "Amount of the last token in the path bought." }
},
"_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bool,address))": {
"details": "Internal version of `transformERC20()`. Only callable from within.",
"params": { "args": "A `TransformERC20Args` struct." },
"returns": { "outputTokenAmount": "The amount of `outputToken` received by the taker." }
@ -1887,14 +2214,6 @@
},
"returns": { "returnResults": "The ABI-encoded results of the underlying calls." }
},
"batchFill((address,address,uint256,(bytes4,uint256,bytes)[]),uint256)": {
"details": "Executes a batch of fills selling `fillData.inputToken` for `fillData.outputToken` in sequence. Refer to the internal variant `_batchFill` for the allowed nested operations.",
"params": {
"fillData": "Encodes the input/output tokens, the sell amount, and the nested operations for this batch fill.",
"minBuyAmount": "The minimum amount of `fillData.outputToken` to buy. Reverts if this amount is not met."
},
"returns": { "outputTokenAmount": "The amount of the output token bought." }
},
"batchFillLimitOrders((address,address,uint128,uint128,uint128,address,address,address,address,bytes32,uint64,uint256)[],(uint8,uint8,bytes32,bytes32)[],uint128[],bool)": {
"details": "Fills multiple limit orders.",
"params": {
@ -1921,6 +2240,18 @@
"takerTokenFilledAmounts": "Array of amounts filled, in taker token."
}
},
"batchFillTakerSignedOtcOrders((address,address,uint128,uint128,address,address,address,uint256)[],(uint8,uint8,bytes32,bytes32)[],(uint8,uint8,bytes32,bytes32)[],bool[])": {
"details": "Fills multiple taker-signed OTC orders.",
"params": {
"makerSignatures": "Array of maker signatures for each order.",
"orders": "Array of OTC orders.",
"takerSignatures": "Array of taker signatures for each order.",
"unwrapWeth": "Array of booleans representing whether or not to unwrap bought WETH into ETH for each order. Should be set to false if the maker token is not WETH."
},
"returns": {
"successes": "Array of booleans representing whether or not each order in `orders` was filled successfully."
}
},
"batchGetLimitOrderRelevantStates((address,address,uint128,uint128,uint128,address,address,address,address,bytes32,uint64,uint256)[],(uint8,uint8,bytes32,bytes32)[])": {
"details": "Batch version of `getLimitOrderRelevantState()`, without reverting. Orders that would normally cause `getLimitOrderRelevantState()` to revert will have empty results.",
"params": { "orders": "The limit orders.", "signatures": "The order signatures." },
@ -2027,13 +2358,24 @@
},
"returns": { "makerTokenFilledAmount": "How much maker token was filled." }
},
"fillOtcOrder((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),uint128,bool)": {
"fillOtcOrder((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),uint128)": {
"details": "Fill an OTC order for up to `takerTokenFillAmount` taker tokens.",
"params": {
"makerSignature": "The order signature from the maker.",
"order": "The OTC order.",
"takerTokenFillAmount": "Maximum taker token amount to fill this order with.",
"unwrapWeth": "Whether or not to unwrap bought WETH into ETH before transferring it to the taker. Should be set to false"
"takerTokenFillAmount": "Maximum taker token amount to fill this order with."
},
"returns": {
"makerTokenFilledAmount": "How much maker token was filled.",
"takerTokenFilledAmount": "How much taker token was filled."
}
},
"fillOtcOrderForEth((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),uint128)": {
"details": "Fill an OTC order for up to `takerTokenFillAmount` taker tokens. Unwraps bought WETH into ETH before sending it to the taker.",
"params": {
"makerSignature": "The order signature from the maker.",
"order": "The OTC order.",
"takerTokenFillAmount": "Maximum taker token amount to fill this order with."
},
"returns": {
"makerTokenFilledAmount": "How much maker token was filled.",
@ -2060,17 +2402,20 @@
"takerTokenFilledAmount": "How much maker token was filled."
}
},
"fillTakerSignedOtcOrder((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),(uint8,uint8,bytes32,bytes32),bool)": {
"fillTakerSignedOtcOrder((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),(uint8,uint8,bytes32,bytes32))": {
"details": "Fully fill an OTC order. \"Meta-transaction\" variant, requires order to be signed by both maker and taker.",
"params": {
"makerSignature": "The order signature from the maker.",
"order": "The OTC order.",
"takerSignature": "The order signature from the taker.",
"unwrapWeth": "Whether or not to unwrap bought WETH into ETH before transferring it to the taker. Should be set to false if the maker token is not WETH."
"takerSignature": "The order signature from the taker."
}
},
"returns": {
"makerTokenFilledAmount": "How much maker token was filled.",
"takerTokenFilledAmount": "How much taker token was filled."
"fillTakerSignedOtcOrderForEth((address,address,uint128,uint128,address,address,address,uint256),(uint8,uint8,bytes32,bytes32),(uint8,uint8,bytes32,bytes32))": {
"details": "Fully fill an OTC order. \"Meta-transaction\" variant, requires order to be signed by both maker and taker. Unwraps bought WETH into ETH before sending it to the taker.",
"params": {
"makerSignature": "The order signature from the maker.",
"order": "The OTC order.",
"takerSignature": "The order signature from the taker."
}
},
"getLimitOrderHash((address,address,uint128,uint128,uint128,address,address,address,address,bytes32,uint64,uint256))": {
@ -2184,13 +2529,62 @@
"target": "The migrator contract address."
}
},
"multiHopFill((address[],uint256,(bytes4,bytes)[]),uint256)": {
"details": "Executes a sequence of fills \"hopping\" through the path of tokens given by `fillData.tokens`. Refer to the internal variant `_multiHopFill` for the allowed nested operations.",
"multiplexBatchSellEthForToken(address,(uint8,uint256,bytes)[],uint256)": {
"details": "Sells attached ETH for `outputToken` using the provided calls.",
"params": {
"fillData": "Encodes the path of tokens, the sell amount, and the nested operations for this multi-hop fill.",
"minBuyAmount": "The minimum amount of the output token to buy. Reverts if this amount is not met."
"calls": "The calls to use to sell the attached ETH.",
"minBuyAmount": "The minimum amount of `outputToken` that must be bought for this function to not revert.",
"outputToken": "The token to buy."
},
"returns": { "outputTokenAmount": "The amount of the output token bought." }
"returns": { "boughtAmount": "The amount of `outputToken` bought." }
},
"multiplexBatchSellTokenForEth(address,(uint8,uint256,bytes)[],uint256,uint256)": {
"details": "Sells `sellAmount` of the given `inputToken` for ETH using the provided calls.",
"params": {
"calls": "The calls to use to sell the input tokens.",
"inputToken": "The token to sell.",
"minBuyAmount": "The minimum amount of ETH that must be bought for this function to not revert.",
"sellAmount": "The amount of `inputToken` to sell."
},
"returns": { "boughtAmount": "The amount of ETH bought." }
},
"multiplexBatchSellTokenForToken(address,address,(uint8,uint256,bytes)[],uint256,uint256)": {
"details": "Sells `sellAmount` of the given `inputToken` for `outputToken` using the provided calls.",
"params": {
"calls": "The calls to use to sell the input tokens.",
"inputToken": "The token to sell.",
"minBuyAmount": "The minimum amount of `outputToken` that must be bought for this function to not revert.",
"outputToken": "The token to buy.",
"sellAmount": "The amount of `inputToken` to sell."
},
"returns": { "boughtAmount": "The amount of `outputToken` bought." }
},
"multiplexMultiHopSellEthForToken(address[],(uint8,bytes)[],uint256)": {
"details": "Sells attached ETH via the given sequence of tokens and calls. `tokens[0]` must be WETH. The last token in `tokens` is the output token that will ultimately be sent to `msg.sender`",
"params": {
"calls": "The sequence of calls to use for the sell.",
"minBuyAmount": "The minimum amount of output tokens that must be bought for this function to not revert.",
"tokens": "The sequence of tokens to use for the sell, i.e. `tokens[i]` will be sold for `tokens[i+1]` via `calls[i]`."
},
"returns": { "boughtAmount": "The amount of output tokens bought." }
},
"multiplexMultiHopSellTokenForEth(address[],(uint8,bytes)[],uint256,uint256)": {
"details": "Sells `sellAmount` of the input token (`tokens[0]`) for ETH via the given sequence of tokens and calls. The last token in `tokens` must be WETH.",
"params": {
"calls": "The sequence of calls to use for the sell.",
"minBuyAmount": "The minimum amount of ETH that must be bought for this function to not revert.",
"tokens": "The sequence of tokens to use for the sell, i.e. `tokens[i]` will be sold for `tokens[i+1]` via `calls[i]`."
},
"returns": { "boughtAmount": "The amount of ETH bought." }
},
"multiplexMultiHopSellTokenForToken(address[],(uint8,bytes)[],uint256,uint256)": {
"details": "Sells `sellAmount` of the input token (`tokens[0]`) via the given sequence of tokens and calls. The last token in `tokens` is the output token that will ultimately be sent to `msg.sender`",
"params": {
"calls": "The sequence of calls to use for the sell.",
"minBuyAmount": "The minimum amount of output tokens that must be bought for this function to not revert.",
"tokens": "The sequence of tokens to use for the sell, i.e. `tokens[i]` will be sold for `tokens[i+1]` via `calls[i]`."
},
"returns": { "boughtAmount": "The amount of output tokens bought." }
},
"owner()": {
"details": "The owner of this contract.",

View File

@ -1,4 +1,13 @@
[
{
"version": "13.18.0",
"changes": [
{
"note": "Update IZeroEx and ITransformERC20 wrappers",
"pr": 282
}
]
},
{
"timestamp": 1631710679,
"version": "13.17.7",

View File

@ -269,12 +269,12 @@ export class ITransformERC20Contract extends BaseContract {
],
},
{
name: 'callDataHash',
type: 'bytes32',
name: 'useSelfBalance',
type: 'bool',
},
{
name: 'callDataSignature',
type: 'bytes',
name: 'recipient',
type: 'address',
},
],
},
@ -497,13 +497,13 @@ export class ITransformERC20Contract extends BaseContract {
inputTokenAmount: BigNumber;
minOutputTokenAmount: BigNumber;
transformations: Array<{ deploymentNonce: number | BigNumber; data: string }>;
callDataHash: string;
callDataSignature: string;
useSelfBalance: boolean;
recipient: string;
}): ContractTxFunctionObj<BigNumber> {
const self = (this as any) as ITransformERC20Contract;
const functionSignature =
'_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bytes32,bytes))';
'_transformERC20((address,address,address,uint256,uint256,(uint32,bytes)[],bool,address))';
return {
async sendTransactionAsync(

File diff suppressed because it is too large Load Diff

View File

@ -126,7 +126,6 @@ export {
IZeroExContract,
IZeroExEventArgs,
IZeroExEvents,
IZeroExExpiredRfqOrderEventArgs,
IZeroExLiquidityProviderSwapEventArgs,
IZeroExMetaTransactionExecutedEventArgs,
IZeroExMigratedEventArgs,

View File

@ -871,21 +871,6 @@
ethereum-types "^3.5.0"
ethereumjs-util "^7.0.10"
"@0x/contracts-zero-ex@^0.27.1":
version "0.27.1"
resolved "https://registry.yarnpkg.com/@0x/contracts-zero-ex/-/contracts-zero-ex-0.27.1.tgz#968fe9d8134972cb464f7c4a33c4e4089ba9218e"
integrity sha512-IDc0pmMtl/92hkhOqlu+dDyIvLtGtwjjE/kdS6x+jwOyNG8sn5sbkwZ3u3PbHk72dND7E0I7BBY9VEXTB1PY/Q==
dependencies:
"@0x/base-contract" "^6.4.0"
"@0x/protocol-utils" "^1.8.1"
"@0x/subproviders" "^6.5.3"
"@0x/types" "^3.3.3"
"@0x/typescript-typings" "^5.2.0"
"@0x/utils" "^6.4.3"
"@0x/web3-wrapper" "^7.5.3"
ethereum-types "^3.5.0"
ethereumjs-util "^7.0.10"
"@0x/dev-utils@^4.2.9":
version "4.2.9"
resolved "https://registry.yarnpkg.com/@0x/dev-utils/-/dev-utils-4.2.9.tgz#b048b139b0055ef3702682c42ccc2a3788a49f5d"
@ -1115,35 +1100,6 @@
solc "^0.5.5"
solidity-parser-antlr "^0.4.2"
"@0x/subproviders@^6.5.3":
version "6.5.3"
resolved "https://registry.yarnpkg.com/@0x/subproviders/-/subproviders-6.5.3.tgz#aec86903527c8f972beec1bc2fbda5fdba361235"
dependencies:
"@0x/assert" "^3.0.27"
"@0x/types" "^3.3.3"
"@0x/typescript-typings" "^5.2.0"
"@0x/utils" "^6.4.3"
"@0x/web3-wrapper" "^7.5.3"
"@ethereumjs/common" "^2.2.0"
"@ethereumjs/tx" "^3.1.3"
"@ledgerhq/hw-app-eth" "^4.3.0"
"@ledgerhq/hw-transport-u2f" "4.24.0"
"@types/hdkey" "^0.7.0"
"@types/node" "12.12.54"
"@types/web3-provider-engine" "^14.0.0"
bip39 "^2.5.0"
bn.js "^4.11.8"
ethereum-types "^3.5.0"
ethereumjs-util "^7.0.10"
ganache-core "^2.13.2"
hdkey "^0.7.1"
json-rpc-error "2.0.0"
lodash "^4.17.11"
semaphore-async-await "^1.5.1"
web3-provider-engine "14.0.6"
optionalDependencies:
"@ledgerhq/hw-transport-node-hid" "^4.3.0"
"@0x/subproviders@^6.6.0":
version "6.6.0"
resolved "https://registry.yarnpkg.com/@0x/subproviders/-/subproviders-6.6.0.tgz#1743d44ae5e2be9ec48caddbf0f1a580f1672d32"
@ -1442,13 +1398,6 @@
web3 "1.2.1"
web3-typescript-typings "^0.10.2"
"@ethereumjs/common@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.2.0.tgz#850a3e3e594ee707ad8d44a11e8152fb62450535"
dependencies:
crc-32 "^1.2.0"
ethereumjs-util "^7.0.9"
"@ethereumjs/common@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.4.0.tgz#2d67f6e6ba22246c5c89104e6b9a119fb3039766"
@ -1457,13 +1406,6 @@
crc-32 "^1.2.0"
ethereumjs-util "^7.1.0"
"@ethereumjs/tx@^3.1.3":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.1.4.tgz#04cf9e9406da5f04a1a26c458744641f4b4b8dd0"
dependencies:
"@ethereumjs/common" "^2.2.0"
ethereumjs-util "^7.0.10"
"@ethereumjs/tx@^3.3.0":
version "3.3.0"
resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.0.tgz#14ed1b7fa0f28e1cd61e3ecbdab824205f6a4378"
@ -6108,7 +6050,7 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum
rlp "^2.0.0"
safe-buffer "^5.1.1"
ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.9:
ethereumjs-util@^7.0.10:
version "7.0.10"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.10.tgz#5fb7b69fa1fda0acc59634cf39d6b0291180fc1f"
dependencies: