From c850046ea0b302f61a5fd24f77bab19784a2adc0 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 19 Dec 2018 16:08:59 -0800 Subject: Dutch Auction Contract Wrapper --- packages/order-utils/src/asset_data_utils.ts | 20 ++++++++++++++++++++ packages/types/src/index.ts | 9 +++++++++ 2 files changed, 29 insertions(+) (limited to 'packages') diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts index f314891e2..0fc166969 100644 --- a/packages/order-utils/src/asset_data_utils.ts +++ b/packages/order-utils/src/asset_data_utils.ts @@ -305,4 +305,24 @@ export const assetDataUtils = { throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`); } }, + /** + * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex + * encoded assetData string, containing information both about the asset being traded and the + * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. + * @param assetData Hex encoded assetData string for the asset being auctioned. + * @param beginTimeSeconds Begin time of the dutch auction. + * @param beginAmount Starting amount being sold in the dutch auction. + * @return The hex encoded assetData string. + */ + encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string { + const assetDataBuffer = ethUtil.toBuffer(assetData); + const abiEncodedAuctionData = (ethAbi as any).rawEncode( + ['uint256', 'uint256'], + [beginTimeSeconds.toString(), beginAmount.toString()], + ); + const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); + const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); + const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); + return dutchAuctionData; + }, }; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 472b56dc2..49f788fb0 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -676,3 +676,12 @@ export interface SimpleEvmOutput { export interface SimpleEvmBytecodeOutput { object: string; } + +export interface DutchAuctionDetails { + beginTimeSeconds: BigNumber; + endTimeSeconds: BigNumber; + beginAmount: BigNumber; + endAmount: BigNumber; + currentAmount: BigNumber; + currentTimeSeconds: BigNumber; +} -- cgit From 43b648e7dc1ea49aff3ab1e6883aa6e069fae72f Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 20 Dec 2018 15:39:19 -0800 Subject: Dutch wrapper --- packages/abi-gen-wrappers/package.json | 2 +- .../src/generated-wrappers/dutch_auction.ts | 322 +++++++++++++++++ packages/abi-gen-wrappers/src/index.ts | 1 + packages/contract-addresses/src/index.ts | 6 + .../contract-artifacts/artifacts/DutchAuction.json | 392 +++++++++++++++++++++ packages/contract-artifacts/src/index.ts | 2 + packages/contract-artifacts/tsconfig.json | 1 + .../contract-wrappers/src/contract_wrappers.ts | 10 + .../src/contract_wrappers/dutch_auction_wrapper.ts | 151 ++++++++ packages/contract-wrappers/src/index.ts | 1 + .../test/dutch_auction_wrapper_test.ts | 156 ++++++++ packages/migrations/src/migration.ts | 9 + packages/order-utils/src/asset_data_utils.ts | 20 -- 13 files changed, 1052 insertions(+), 21 deletions(-) create mode 100644 packages/abi-gen-wrappers/src/generated-wrappers/dutch_auction.ts create mode 100644 packages/contract-artifacts/artifacts/DutchAuction.json create mode 100644 packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts create mode 100644 packages/contract-wrappers/test/dutch_auction_wrapper_test.ts (limited to 'packages') diff --git a/packages/abi-gen-wrappers/package.json b/packages/abi-gen-wrappers/package.json index 25ba3a6e0..38b5e9a9b 100644 --- a/packages/abi-gen-wrappers/package.json +++ b/packages/abi-gen-wrappers/package.json @@ -18,7 +18,7 @@ "generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output src/generated-wrappers --backend ethers" }, "config": { - "abis": "../contract-artifacts/artifacts/@(AssetProxyOwner|DummyERC20Token|DummyERC721Token|ERC20Proxy|ERC20Token|ERC721Proxy|ERC721Token|Exchange|Forwarder|IValidator|IWallet|OrderValidator|WETH9|ZRXToken).json" + "abis": "../contract-artifacts/artifacts/@(AssetProxyOwner|DutchAuction|DummyERC20Token|DummyERC721Token|ERC20Proxy|ERC20Token|ERC721Proxy|ERC721Token|Exchange|Forwarder|IValidator|IWallet|OrderValidator|WETH9|ZRXToken).json" }, "repository": { "type": "git", diff --git a/packages/abi-gen-wrappers/src/generated-wrappers/dutch_auction.ts b/packages/abi-gen-wrappers/src/generated-wrappers/dutch_auction.ts new file mode 100644 index 000000000..90e233756 --- /dev/null +++ b/packages/abi-gen-wrappers/src/generated-wrappers/dutch_auction.ts @@ -0,0 +1,322 @@ +// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma whitespace class-name +// tslint:disable:no-unused-variable +// tslint:disable:no-unbound-method +import { BaseContract } from '@0x/base-contract'; +import { BlockParam, BlockParamLiteral, CallData, ContractAbi, ContractArtifact, DecodedLogArgs, MethodAbi, Provider, TxData, TxDataPayable } from 'ethereum-types'; +import { BigNumber, classUtils, logUtils } from '@0x/utils'; +import { SimpleContractArtifact } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import * as ethers from 'ethers'; +import * as _ from 'lodash'; +// tslint:enable:no-unused-variable + + +/* istanbul ignore next */ +// tslint:disable:no-parameter-reassignment +// tslint:disable-next-line:class-name +export class DutchAuctionContract extends BaseContract { + public getAuctionDetails = { + async sendTransactionAsync( + order: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + txData: Partial = {}, + ): Promise { + const self = this as any as DutchAuctionContract; + const inputAbi = self._lookupAbi('getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})').inputs; + [order + ] = BaseContract._formatABIDataItemList(inputAbi, [order + ], BaseContract._bigNumberToString.bind(self)); + BaseContract.strictArgumentEncodingCheck(inputAbi, [order + ]); + const encodedData = self._lookupEthersInterface('getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})').functions.getAuctionDetails.encode([order + ]); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + self.getAuctionDetails.estimateGasAsync.bind( + self, + order + ), + ); + const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + return txHash; + }, + async estimateGasAsync( + order: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + txData: Partial = {}, + ): Promise { + const self = this as any as DutchAuctionContract; + const inputAbi = self._lookupAbi('getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})').inputs; + [order + ] = BaseContract._formatABIDataItemList(inputAbi, [order + ], BaseContract._bigNumberToString); + const encodedData = self._lookupEthersInterface('getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})').functions.getAuctionDetails.encode([order + ]); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + return gas; + }, + getABIEncodedTransactionData( + order: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + ): string { + const self = this as any as DutchAuctionContract; + const inputAbi = self._lookupAbi('getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})').inputs; + [order + ] = BaseContract._formatABIDataItemList(inputAbi, [order + ], BaseContract._bigNumberToString); + const abiEncodedTransactionData = self._lookupEthersInterface('getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})').functions.getAuctionDetails.encode([order + ]); + return abiEncodedTransactionData; + }, + async callAsync( + order: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise<{beginTimeSeconds: BigNumber;endTimeSeconds: BigNumber;beginAmount: BigNumber;endAmount: BigNumber;currentAmount: BigNumber;currentTimeSeconds: BigNumber} + > { + const self = this as any as DutchAuctionContract; + const functionSignature = 'getAuctionDetails({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes})'; + const inputAbi = self._lookupAbi(functionSignature).inputs; + [order + ] = BaseContract._formatABIDataItemList(inputAbi, [order + ], BaseContract._bigNumberToString.bind(self)); + BaseContract.strictArgumentEncodingCheck(inputAbi, [order + ]); + const ethersFunction = self._lookupEthersInterface(functionSignature).functions.getAuctionDetails; + const encodedData = ethersFunction.encode([order + ]); + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...callData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + const rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + BaseContract._throwIfRevertWithReasonCallResult(rawCallResult); + let resultArray = ethersFunction.decode(rawCallResult); + const outputAbi = (_.find(self.abi, {name: 'getAuctionDetails'}) as MethodAbi).outputs; + resultArray = BaseContract._formatABIDataItemList(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); + resultArray = BaseContract._formatABIDataItemList(outputAbi, resultArray, BaseContract._bnToBigNumber.bind(this)); + return resultArray[0]; + }, + }; + public matchOrders = { + async sendTransactionAsync( + buyOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + sellOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + buySignature: string, + sellSignature: string, + txData: Partial = {}, + ): Promise { + const self = this as any as DutchAuctionContract; + const inputAbi = self._lookupAbi('matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)').inputs; + [buyOrder, + sellOrder, + buySignature, + sellSignature + ] = BaseContract._formatABIDataItemList(inputAbi, [buyOrder, + sellOrder, + buySignature, + sellSignature + ], BaseContract._bigNumberToString.bind(self)); + BaseContract.strictArgumentEncodingCheck(inputAbi, [buyOrder, + sellOrder, + buySignature, + sellSignature + ]); + const encodedData = self._lookupEthersInterface('matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)').functions.matchOrders.encode([buyOrder, + sellOrder, + buySignature, + sellSignature + ]); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + self.matchOrders.estimateGasAsync.bind( + self, + buyOrder, + sellOrder, + buySignature, + sellSignature + ), + ); + const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + return txHash; + }, + async estimateGasAsync( + buyOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + sellOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + buySignature: string, + sellSignature: string, + txData: Partial = {}, + ): Promise { + const self = this as any as DutchAuctionContract; + const inputAbi = self._lookupAbi('matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)').inputs; + [buyOrder, + sellOrder, + buySignature, + sellSignature + ] = BaseContract._formatABIDataItemList(inputAbi, [buyOrder, + sellOrder, + buySignature, + sellSignature + ], BaseContract._bigNumberToString); + const encodedData = self._lookupEthersInterface('matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)').functions.matchOrders.encode([buyOrder, + sellOrder, + buySignature, + sellSignature + ]); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...txData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + return gas; + }, + getABIEncodedTransactionData( + buyOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + sellOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + buySignature: string, + sellSignature: string, + ): string { + const self = this as any as DutchAuctionContract; + const inputAbi = self._lookupAbi('matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)').inputs; + [buyOrder, + sellOrder, + buySignature, + sellSignature + ] = BaseContract._formatABIDataItemList(inputAbi, [buyOrder, + sellOrder, + buySignature, + sellSignature + ], BaseContract._bigNumberToString); + const abiEncodedTransactionData = self._lookupEthersInterface('matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)').functions.matchOrders.encode([buyOrder, + sellOrder, + buySignature, + sellSignature + ]); + return abiEncodedTransactionData; + }, + async callAsync( + buyOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + sellOrder: {makerAddress: string;takerAddress: string;feeRecipientAddress: string;senderAddress: string;makerAssetAmount: BigNumber;takerAssetAmount: BigNumber;makerFee: BigNumber;takerFee: BigNumber;expirationTimeSeconds: BigNumber;salt: BigNumber;makerAssetData: string;takerAssetData: string}, + buySignature: string, + sellSignature: string, + callData: Partial = {}, + defaultBlock?: BlockParam, + ): Promise<{left: {makerAssetFilledAmount: BigNumber;takerAssetFilledAmount: BigNumber;makerFeePaid: BigNumber;takerFeePaid: BigNumber};right: {makerAssetFilledAmount: BigNumber;takerAssetFilledAmount: BigNumber;makerFeePaid: BigNumber;takerFeePaid: BigNumber};leftMakerAssetSpreadAmount: BigNumber} + > { + const self = this as any as DutchAuctionContract; + const functionSignature = 'matchOrders({address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},{address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes},bytes,bytes)'; + const inputAbi = self._lookupAbi(functionSignature).inputs; + [buyOrder, + sellOrder, + buySignature, + sellSignature + ] = BaseContract._formatABIDataItemList(inputAbi, [buyOrder, + sellOrder, + buySignature, + sellSignature + ], BaseContract._bigNumberToString.bind(self)); + BaseContract.strictArgumentEncodingCheck(inputAbi, [buyOrder, + sellOrder, + buySignature, + sellSignature + ]); + const ethersFunction = self._lookupEthersInterface(functionSignature).functions.matchOrders; + const encodedData = ethersFunction.encode([buyOrder, + sellOrder, + buySignature, + sellSignature + ]); + const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + { + to: self.address, + ...callData, + data: encodedData, + }, + self._web3Wrapper.getContractDefaults(), + ); + const rawCallResult = await self._web3Wrapper.callAsync(callDataWithDefaults, defaultBlock); + BaseContract._throwIfRevertWithReasonCallResult(rawCallResult); + let resultArray = ethersFunction.decode(rawCallResult); + const outputAbi = (_.find(self.abi, {name: 'matchOrders'}) as MethodAbi).outputs; + resultArray = BaseContract._formatABIDataItemList(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); + resultArray = BaseContract._formatABIDataItemList(outputAbi, resultArray, BaseContract._bnToBigNumber.bind(this)); + return resultArray[0]; + }, + }; + public static async deployFrom0xArtifactAsync( + artifact: ContractArtifact | SimpleContractArtifact, + provider: Provider, + txDefaults: Partial, + _exchange: string, + ): Promise { + if (_.isUndefined(artifact.compilerOutput)) { + throw new Error('Compiler output not found in the artifact file'); + } + const bytecode = artifact.compilerOutput.evm.bytecode.object; + const abi = artifact.compilerOutput.abi; + return DutchAuctionContract.deployAsync(bytecode, abi, provider, txDefaults, _exchange +); + } + public static async deployAsync( + bytecode: string, + abi: ContractAbi, + provider: Provider, + txDefaults: Partial, + _exchange: string, + ): Promise { + const constructorAbi = BaseContract._lookupConstructorAbi(abi); + [_exchange +] = BaseContract._formatABIDataItemList( + constructorAbi.inputs, + [_exchange +], + BaseContract._bigNumberToString, + ); + const iface = new ethers.utils.Interface(abi); + const deployInfo = iface.deployFunction; + const txData = deployInfo.encode(bytecode, [_exchange +]); + const web3Wrapper = new Web3Wrapper(provider); + const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( + {data: txData}, + txDefaults, + web3Wrapper.estimateGasAsync.bind(web3Wrapper), + ); + const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); + logUtils.log(`transactionHash: ${txHash}`); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); + logUtils.log(`DutchAuction successfully deployed at ${txReceipt.contractAddress}`); + const contractInstance = new DutchAuctionContract(abi, txReceipt.contractAddress as string, provider, txDefaults); + contractInstance.constructorArgs = [_exchange +]; + return contractInstance; + } + constructor(abi: ContractAbi, address: string, provider: Provider, txDefaults?: Partial) { + super('DutchAuction', abi, address, provider, txDefaults); + classUtils.bindAll(this, ['_ethersInterfacesByFunctionSignature', 'address', 'abi', '_web3Wrapper']); + } +} // tslint:disable:max-file-line-count +// tslint:enable:no-unbound-method diff --git a/packages/abi-gen-wrappers/src/index.ts b/packages/abi-gen-wrappers/src/index.ts index de418214b..b5a7d0cfe 100644 --- a/packages/abi-gen-wrappers/src/index.ts +++ b/packages/abi-gen-wrappers/src/index.ts @@ -1,6 +1,7 @@ export * from './generated-wrappers/asset_proxy_owner'; export * from './generated-wrappers/dummy_erc20_token'; export * from './generated-wrappers/dummy_erc721_token'; +export * from './generated-wrappers/dutch_auction'; export * from './generated-wrappers/erc20_proxy'; export * from './generated-wrappers/erc20_token'; export * from './generated-wrappers/erc721_proxy'; diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index 7989631e3..5b8e95174 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -9,6 +9,7 @@ export interface ContractAddresses { assetProxyOwner: string; forwarder: string; orderValidator: string; + dutchAuction: string; } export enum NetworkId { @@ -29,6 +30,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6', forwarder: '0x5468a1dc173652ee28d249c271fa9933144746b1', orderValidator: '0x9463e518dea6810309563c81d5266c1b1d149138', + dutchAuction: '0x', }, 3: { erc20Proxy: '0xb1408f4c245a23c31b98d2c626777d4c0d766caa', @@ -39,6 +41,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b', forwarder: '0x2240dab907db71e64d3e0dba4800c83b5c502d4e', orderValidator: '0x90431a90516ab49af23a0530e04e8c7836e7122f', + dutchAuction: '0x', }, 4: { exchange: '0xbce0b5f6eb618c565c3e5f5cd69652bbc279f44e', @@ -49,6 +52,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0xe1703da878afcebff5b7624a826902af475b9c03', forwarder: '0x2d40589abbdee84961f3a7656b9af7adb0ee5ab4', orderValidator: '0x0c5173a51e26b29d6126c686756fb9fbef71f762', + dutchAuction: '0x', }, 42: { erc20Proxy: '0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e', @@ -59,6 +63,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x2c824d2882baa668e0d5202b1e7f2922278703f8', forwarder: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6', orderValidator: '0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d', + dutchAuction: '0x', }, // NetworkId 50 represents our Ganache snapshot generated from migrations. 50: { @@ -70,6 +75,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x34d402f14d58e001d8efbe6585051bf9706aa064', forwarder: '0xb69e673309512a9d726f87304c6984054f87a93b', orderValidator: '0xe86bb98fcf9bff3512c74589b78fb168200cc546', + dutchAuction: '0x', }, }; diff --git a/packages/contract-artifacts/artifacts/DutchAuction.json b/packages/contract-artifacts/artifacts/DutchAuction.json new file mode 100644 index 000000000..2c1998034 --- /dev/null +++ b/packages/contract-artifacts/artifacts/DutchAuction.json @@ -0,0 +1,392 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "DutchAuction", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "components": [ + { + "name": "makerAddress", + "type": "address" + }, + { + "name": "takerAddress", + "type": "address" + }, + { + "name": "feeRecipientAddress", + "type": "address" + }, + { + "name": "senderAddress", + "type": "address" + }, + { + "name": "makerAssetAmount", + "type": "uint256" + }, + { + "name": "takerAssetAmount", + "type": "uint256" + }, + { + "name": "makerFee", + "type": "uint256" + }, + { + "name": "takerFee", + "type": "uint256" + }, + { + "name": "expirationTimeSeconds", + "type": "uint256" + }, + { + "name": "salt", + "type": "uint256" + }, + { + "name": "makerAssetData", + "type": "bytes" + }, + { + "name": "takerAssetData", + "type": "bytes" + } + ], + "name": "order", + "type": "tuple" + } + ], + "name": "getAuctionDetails", + "outputs": [ + { + "components": [ + { + "name": "beginTimeSeconds", + "type": "uint256" + }, + { + "name": "endTimeSeconds", + "type": "uint256" + }, + { + "name": "beginAmount", + "type": "uint256" + }, + { + "name": "endAmount", + "type": "uint256" + }, + { + "name": "currentAmount", + "type": "uint256" + }, + { + "name": "currentTimeSeconds", + "type": "uint256" + } + ], + "name": "auctionDetails", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "components": [ + { + "name": "makerAddress", + "type": "address" + }, + { + "name": "takerAddress", + "type": "address" + }, + { + "name": "feeRecipientAddress", + "type": "address" + }, + { + "name": "senderAddress", + "type": "address" + }, + { + "name": "makerAssetAmount", + "type": "uint256" + }, + { + "name": "takerAssetAmount", + "type": "uint256" + }, + { + "name": "makerFee", + "type": "uint256" + }, + { + "name": "takerFee", + "type": "uint256" + }, + { + "name": "expirationTimeSeconds", + "type": "uint256" + }, + { + "name": "salt", + "type": "uint256" + }, + { + "name": "makerAssetData", + "type": "bytes" + }, + { + "name": "takerAssetData", + "type": "bytes" + } + ], + "name": "buyOrder", + "type": "tuple" + }, + { + "components": [ + { + "name": "makerAddress", + "type": "address" + }, + { + "name": "takerAddress", + "type": "address" + }, + { + "name": "feeRecipientAddress", + "type": "address" + }, + { + "name": "senderAddress", + "type": "address" + }, + { + "name": "makerAssetAmount", + "type": "uint256" + }, + { + "name": "takerAssetAmount", + "type": "uint256" + }, + { + "name": "makerFee", + "type": "uint256" + }, + { + "name": "takerFee", + "type": "uint256" + }, + { + "name": "expirationTimeSeconds", + "type": "uint256" + }, + { + "name": "salt", + "type": "uint256" + }, + { + "name": "makerAssetData", + "type": "bytes" + }, + { + "name": "takerAssetData", + "type": "bytes" + } + ], + "name": "sellOrder", + "type": "tuple" + }, + { + "name": "buySignature", + "type": "bytes" + }, + { + "name": "sellSignature", + "type": "bytes" + } + ], + "name": "matchOrders", + "outputs": [ + { + "components": [ + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "left", + "type": "tuple" + }, + { + "components": [ + { + "name": "makerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "takerAssetFilledAmount", + "type": "uint256" + }, + { + "name": "makerFeePaid", + "type": "uint256" + }, + { + "name": "takerFeePaid", + "type": "uint256" + } + ], + "name": "right", + "type": "tuple" + }, + { + "name": "leftMakerAssetSpreadAmount", + "type": "uint256" + } + ], + "name": "matchedFillResults", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "_exchange", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x608060405234801561001057600080fd5b50604051602080611352833981018060405261002f9190810190610067565b60008054600160a060020a031916600160a060020a0392909216919091179055610099565b6000610060825161008d565b9392505050565b60006020828403121561007957600080fd5b60006100858484610054565b949350505050565b600160a060020a031690565b6112aa806100a86000396000f30060806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632e9cd03381146100505780633c28d86114610086575b600080fd5b34801561005c57600080fd5b5061007061006b366004610b25565b6100b3565b60405161007d919061110a565b60405180910390f35b34801561009257600080fd5b506100a66100a1366004610b5a565b61029c565b60405161007d9190611118565b6100bb6107b1565b610140820151516000808080808080606488101561010e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110aa565b60405180910390fd5b6101408a0151610146907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a0163ffffffff6105f216565b6101408b0151909750610181907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a0163ffffffff6105f216565b9550868a61010001511115156101c3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110ba565b868a61010001510394508960a001519350838611151561020f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110fa565b50505083865261010087018051602088015260408701849052606087018290524260a088018190529051828503919081900386821015610255576080890186905261028f565b6101008a0151821061026d576080890184905261028f565b6102898461028461027e8487610607565b8861066d565b610684565b60808a01525b5050505050505050919050565b6102a46107e8565b6102ac6107b1565b6000606060008060006102be8a6100b3565b805160a08201519197501115610300576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110ea565b60a08601516101008b015111610342576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110ca565b608080870151908c01511015610384576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110fa565b6000546040517f3c28d86100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633c28d861906103e0908e908e908e908e90600401611127565b61012060405180830381600087803b1580156103fb57600080fd5b505af115801561040f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104339190810190610b06565b96508660400151945060008511156105e4576101608a0151935061045e84601063ffffffff6106c316565b92506104728b608001518760800151610724565b915061047e8583610724565b905060008111156105325789516040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169163a9059cbb916104de9190859060040161105f565b602060405180830381600087803b1580156104f857600080fd5b505af115801561050c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105309190810190610ae0565b505b60008211156105e4578a516040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169163a9059cbb916105909190869060040161105f565b602060405180830381600087803b1580156105aa57600080fd5b505af11580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105e29190810190610ae0565b505b505050505050949350505050565b60006105fe8383610766565b90505b92915050565b60008083151561061a5760009150610666565b5082820282848281151561062a57fe5b0414610662576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061109a565b8091505b5092915050565b600080828481151561067b57fe5b04949350505050565b600082820183811015610662576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061109a565b600081601401835110151515610705576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110da565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b600082821115610760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061107a565b50900390565b6000816020018351101515156107a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061108a565b50016020015190565b60c0604051908101604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b610120604051908101604052806107fd610817565b815260200161080a610817565b8152602001600081525090565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b600061084c82356111ef565b9392505050565b600061084c825161120b565b6000601f8201831361087057600080fd5b813561088361087e826111a5565b61117e565b9150808252602083016020830185838301111561089f57600080fd5b6108aa838284611210565b50505092915050565b6000608082840312156108c557600080fd5b6108cf608061117e565b905060006108dd8484610ad4565b82525060206108ee84848301610ad4565b602083015250604061090284828501610ad4565b604083015250606061091684828501610ad4565b60608301525092915050565b6000610120828403121561093557600080fd5b61093f606061117e565b9050600061094d84846108b3565b825250608061095e848483016108b3565b60208301525061010061097384828501610ad4565b60408301525092915050565b6000610180828403121561099257600080fd5b61099d61018061117e565b905060006109ab8484610840565b82525060206109bc84848301610840565b60208301525060406109d084828501610840565b60408301525060606109e484828501610840565b60608301525060806109f884828501610ac8565b60808301525060a0610a0c84828501610ac8565b60a08301525060c0610a2084828501610ac8565b60c08301525060e0610a3484828501610ac8565b60e083015250610100610a4984828501610ac8565b61010083015250610120610a5f84828501610ac8565b6101208301525061014082013567ffffffffffffffff811115610a8157600080fd5b610a8d8482850161085f565b6101408301525061016082013567ffffffffffffffff811115610aaf57600080fd5b610abb8482850161085f565b6101608301525092915050565b600061084c8235611208565b600061084c8251611208565b600060208284031215610af257600080fd5b6000610afe8484610853565b949350505050565b60006101208284031215610b1957600080fd5b6000610afe8484610922565b600060208284031215610b3757600080fd5b813567ffffffffffffffff811115610b4e57600080fd5b610afe8482850161097f565b60008060008060808587031215610b7057600080fd5b843567ffffffffffffffff811115610b8757600080fd5b610b938782880161097f565b945050602085013567ffffffffffffffff811115610bb057600080fd5b610bbc8782880161097f565b935050604085013567ffffffffffffffff811115610bd957600080fd5b610be58782880161085f565b925050606085013567ffffffffffffffff811115610c0257600080fd5b610c0e8782880161085f565b91505092959194509250565b610c23816111ef565b82525050565b6000610c34826111eb565b808452610c4881602086016020860161121c565b610c5181611248565b9093016020019392505050565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601281527f494e56414c49445f41535345545f444154410000000000000000000000000000602082015260400190565b601281527f494e56414c49445f424547494e5f54494d450000000000000000000000000000602082015260400190565b600f81527f41554354494f4e5f455850495245440000000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601381527f41554354494f4e5f4e4f545f5354415254454400000000000000000000000000602082015260400190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160c0830190610e6b8482611056565b506020820151610e7e6020850182611056565b506040820151610e916040850182611056565b506060820151610ea46060850182611056565b506080820151610eb76080850182611056565b5060a0820151610eca60a0850182611056565b50505050565b80516080830190610ee18482611056565b506020820151610ef46020850182611056565b506040820151610f076040850182611056565b506060820151610eca6060850182611056565b8051610120830190610f2c8482610ed0565b506020820151610f3f6080850182610ed0565b506040820151610eca610100850182611056565b8051600090610180840190610f688582610c1a565b506020830151610f7b6020860182610c1a565b506040830151610f8e6040860182610c1a565b506060830151610fa16060860182610c1a565b506080830151610fb46080860182611056565b5060a0830151610fc760a0860182611056565b5060c0830151610fda60c0860182611056565b5060e0830151610fed60e0860182611056565b50610100830151611002610100860182611056565b50610120830151611017610120860182611056565b506101408301518482036101408601526110318282610c29565b91505061016083015184820361016086015261104d8282610c29565b95945050505050565b610c2381611208565b6040810161106d8285610c1a565b61084c6020830184611056565b6020808252810161060181610c5e565b6020808252810161060181610c8e565b6020808252810161060181610ce4565b6020808252810161060181610d14565b6020808252810161060181610d44565b6020808252810161060181610d74565b6020808252810161060181610da4565b6020808252810161060181610dfa565b6020808252810161060181610e2a565b60c081016106018284610e5a565b61012081016106018284610f1a565b608080825281016111388187610f53565b9050818103602083015261114c8186610f53565b905081810360408301526111608185610c29565b905081810360608301526111748184610c29565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561119d57600080fd5b604052919050565b600067ffffffffffffffff8211156111bc57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b151590565b82818337506000910152565b60005b8381101561123757818101518382015260200161121f565b83811115610eca5750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a723058209cf70b04b75fc23e6762ae4c6c8f25ccad25dfcb39cf1dd3966eb27ce513de036c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH2 0x1352 DUP4 CODECOPY DUP2 ADD DUP1 PUSH1 0x40 MSTORE PUSH2 0x2F SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0x67 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP3 SWAP1 SWAP3 AND SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH2 0x99 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x60 DUP3 MLOAD PUSH2 0x8D JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x79 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x85 DUP5 DUP5 PUSH2 0x54 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND SWAP1 JUMP JUMPDEST PUSH2 0x12AA DUP1 PUSH2 0xA8 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4B JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2E9CD033 DUP2 EQ PUSH2 0x50 JUMPI DUP1 PUSH4 0x3C28D861 EQ PUSH2 0x86 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x70 PUSH2 0x6B CALLDATASIZE PUSH1 0x4 PUSH2 0xB25 JUMP JUMPDEST PUSH2 0xB3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x7D SWAP2 SWAP1 PUSH2 0x110A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x92 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA6 PUSH2 0xA1 CALLDATASIZE PUSH1 0x4 PUSH2 0xB5A JUMP JUMPDEST PUSH2 0x29C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x7D SWAP2 SWAP1 PUSH2 0x1118 JUMP JUMPDEST PUSH2 0xBB PUSH2 0x7B1 JUMP JUMPDEST PUSH2 0x140 DUP3 ADD MLOAD MLOAD PUSH1 0x0 DUP1 DUP1 DUP1 DUP1 DUP1 DUP1 PUSH1 0x64 DUP9 LT ISZERO PUSH2 0x10E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10AA JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x140 DUP11 ADD MLOAD PUSH2 0x146 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP11 ADD PUSH4 0xFFFFFFFF PUSH2 0x5F2 AND JUMP JUMPDEST PUSH2 0x140 DUP12 ADD MLOAD SWAP1 SWAP8 POP PUSH2 0x181 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP11 ADD PUSH4 0xFFFFFFFF PUSH2 0x5F2 AND JUMP JUMPDEST SWAP6 POP DUP7 DUP11 PUSH2 0x100 ADD MLOAD GT ISZERO ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10BA JUMP JUMPDEST DUP7 DUP11 PUSH2 0x100 ADD MLOAD SUB SWAP5 POP DUP10 PUSH1 0xA0 ADD MLOAD SWAP4 POP DUP4 DUP7 GT ISZERO ISZERO PUSH2 0x20F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10FA JUMP JUMPDEST POP POP POP DUP4 DUP7 MSTORE PUSH2 0x100 DUP8 ADD DUP1 MLOAD PUSH1 0x20 DUP9 ADD MSTORE PUSH1 0x40 DUP8 ADD DUP5 SWAP1 MSTORE PUSH1 0x60 DUP8 ADD DUP3 SWAP1 MSTORE TIMESTAMP PUSH1 0xA0 DUP9 ADD DUP2 SWAP1 MSTORE SWAP1 MLOAD DUP3 DUP6 SUB SWAP2 SWAP1 DUP2 SWAP1 SUB DUP7 DUP3 LT ISZERO PUSH2 0x255 JUMPI PUSH1 0x80 DUP10 ADD DUP7 SWAP1 MSTORE PUSH2 0x28F JUMP JUMPDEST PUSH2 0x100 DUP11 ADD MLOAD DUP3 LT PUSH2 0x26D JUMPI PUSH1 0x80 DUP10 ADD DUP5 SWAP1 MSTORE PUSH2 0x28F JUMP JUMPDEST PUSH2 0x289 DUP5 PUSH2 0x284 PUSH2 0x27E DUP5 DUP8 PUSH2 0x607 JUMP JUMPDEST DUP9 PUSH2 0x66D JUMP JUMPDEST PUSH2 0x684 JUMP JUMPDEST PUSH1 0x80 DUP11 ADD MSTORE JUMPDEST POP POP POP POP POP POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2A4 PUSH2 0x7E8 JUMP JUMPDEST PUSH2 0x2AC PUSH2 0x7B1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x2BE DUP11 PUSH2 0xB3 JUMP JUMPDEST DUP1 MLOAD PUSH1 0xA0 DUP3 ADD MLOAD SWAP2 SWAP8 POP GT ISZERO PUSH2 0x300 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10EA JUMP JUMPDEST PUSH1 0xA0 DUP7 ADD MLOAD PUSH2 0x100 DUP12 ADD MLOAD GT PUSH2 0x342 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10CA JUMP JUMPDEST PUSH1 0x80 DUP1 DUP8 ADD MLOAD SWAP1 DUP13 ADD MLOAD LT ISZERO PUSH2 0x384 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10FA JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH1 0x40 MLOAD PUSH32 0x3C28D86100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x3C28D861 SWAP1 PUSH2 0x3E0 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x1127 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x3FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x40F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x433 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0xB06 JUMP JUMPDEST SWAP7 POP DUP7 PUSH1 0x40 ADD MLOAD SWAP5 POP PUSH1 0x0 DUP6 GT ISZERO PUSH2 0x5E4 JUMPI PUSH2 0x160 DUP11 ADD MLOAD SWAP4 POP PUSH2 0x45E DUP5 PUSH1 0x10 PUSH4 0xFFFFFFFF PUSH2 0x6C3 AND JUMP JUMPDEST SWAP3 POP PUSH2 0x472 DUP12 PUSH1 0x80 ADD MLOAD DUP8 PUSH1 0x80 ADD MLOAD PUSH2 0x724 JUMP JUMPDEST SWAP2 POP PUSH2 0x47E DUP6 DUP4 PUSH2 0x724 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 GT ISZERO PUSH2 0x532 JUMPI DUP10 MLOAD PUSH1 0x40 MLOAD PUSH32 0xA9059CBB00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP2 PUSH4 0xA9059CBB SWAP2 PUSH2 0x4DE SWAP2 SWAP1 DUP6 SWAP1 PUSH1 0x4 ADD PUSH2 0x105F JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x4F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x50C JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x530 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0xAE0 JUMP JUMPDEST POP JUMPDEST PUSH1 0x0 DUP3 GT ISZERO PUSH2 0x5E4 JUMPI DUP11 MLOAD PUSH1 0x40 MLOAD PUSH32 0xA9059CBB00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP2 PUSH4 0xA9059CBB SWAP2 PUSH2 0x590 SWAP2 SWAP1 DUP7 SWAP1 PUSH1 0x4 ADD PUSH2 0x105F JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x5AA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x5BE JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x5E2 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0xAE0 JUMP JUMPDEST POP JUMPDEST POP POP POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x5FE DUP4 DUP4 PUSH2 0x766 JUMP JUMPDEST SWAP1 POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 ISZERO ISZERO PUSH2 0x61A JUMPI PUSH1 0x0 SWAP2 POP PUSH2 0x666 JUMP JUMPDEST POP DUP3 DUP3 MUL DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x62A JUMPI INVALID JUMPDEST DIV EQ PUSH2 0x662 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x109A JUMP JUMPDEST DUP1 SWAP2 POP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x67B JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0x662 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x109A JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x705 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10DA JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x760 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x107A JUMP JUMPDEST POP SWAP1 SUB SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x7A8 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x108A JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0xC0 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x7FD PUSH2 0x817 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x80A PUSH2 0x817 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 CALLDATALOAD PUSH2 0x11EF JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 MLOAD PUSH2 0x120B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x870 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x883 PUSH2 0x87E DUP3 PUSH2 0x11A5 JUMP JUMPDEST PUSH2 0x117E JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x89F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x8AA DUP4 DUP3 DUP5 PUSH2 0x1210 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x8C5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x8CF PUSH1 0x80 PUSH2 0x117E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x8DD DUP5 DUP5 PUSH2 0xAD4 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x8EE DUP5 DUP5 DUP4 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x902 DUP5 DUP3 DUP6 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x916 DUP5 DUP3 DUP6 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x120 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x935 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x93F PUSH1 0x60 PUSH2 0x117E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x94D DUP5 DUP5 PUSH2 0x8B3 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x80 PUSH2 0x95E DUP5 DUP5 DUP4 ADD PUSH2 0x8B3 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x973 DUP5 DUP3 DUP6 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x992 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x99D PUSH2 0x180 PUSH2 0x117E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x9AB DUP5 DUP5 PUSH2 0x840 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x9BC DUP5 DUP5 DUP4 ADD PUSH2 0x840 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x9D0 DUP5 DUP3 DUP6 ADD PUSH2 0x840 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x9E4 DUP5 DUP3 DUP6 ADD PUSH2 0x840 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x9F8 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0xA0C DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0xA20 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0xA34 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0xA49 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0xA5F DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xA81 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA8D DUP5 DUP3 DUP6 ADD PUSH2 0x85F JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xAAF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xABB DUP5 DUP3 DUP6 ADD PUSH2 0x85F JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 CALLDATALOAD PUSH2 0x1208 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 MLOAD PUSH2 0x1208 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xAF2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAFE DUP5 DUP5 PUSH2 0x853 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x120 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB19 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAFE DUP5 DUP5 PUSH2 0x922 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB37 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xAFE DUP5 DUP3 DUP6 ADD PUSH2 0x97F JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB70 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB87 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB93 DUP8 DUP3 DUP9 ADD PUSH2 0x97F JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBB0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBBC DUP8 DUP3 DUP9 ADD PUSH2 0x97F JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBD9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBE5 DUP8 DUP3 DUP9 ADD PUSH2 0x85F JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC02 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC0E DUP8 DUP3 DUP9 ADD PUSH2 0x85F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0xC23 DUP2 PUSH2 0x11EF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC34 DUP3 PUSH2 0x11EB JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0xC48 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x121C JUMP JUMPDEST PUSH2 0xC51 DUP2 PUSH2 0x1248 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x55494E543235365F554E444552464C4F57000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x55494E543235365F4F564552464C4F5700000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x494E56414C49445F41535345545F444154410000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x494E56414C49445F424547494E5F54494D450000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x41554354494F4E5F455850495245440000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x41554354494F4E5F4E4F545F5354415254454400000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F414D4F554E54000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0xC0 DUP4 ADD SWAP1 PUSH2 0xE6B DUP5 DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0xE7E PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0xE91 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0xEA4 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x80 DUP3 ADD MLOAD PUSH2 0xEB7 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xA0 DUP3 ADD MLOAD PUSH2 0xECA PUSH1 0xA0 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0xEE1 DUP5 DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0xEF4 PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0xF07 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0xECA PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST DUP1 MLOAD PUSH2 0x120 DUP4 ADD SWAP1 PUSH2 0xF2C DUP5 DUP3 PUSH2 0xED0 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0xF3F PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0xED0 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0xECA PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0xF68 DUP6 DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0xF7B PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0xF8E PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0xFA1 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0xFB4 PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0xFC7 PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0xFDA PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0xFED PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0x1002 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0x1017 PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0x1031 DUP3 DUP3 PUSH2 0xC29 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0x104D DUP3 DUP3 PUSH2 0xC29 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0xC23 DUP2 PUSH2 0x1208 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x106D DUP3 DUP6 PUSH2 0xC1A JUMP JUMPDEST PUSH2 0x84C PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1056 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xC5E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xC8E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xCE4 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xD14 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xD44 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xD74 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xDA4 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xDFA JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xE2A JUMP JUMPDEST PUSH1 0xC0 DUP2 ADD PUSH2 0x601 DUP3 DUP5 PUSH2 0xE5A JUMP JUMPDEST PUSH2 0x120 DUP2 ADD PUSH2 0x601 DUP3 DUP5 PUSH2 0xF1A JUMP JUMPDEST PUSH1 0x80 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x1138 DUP2 DUP8 PUSH2 0xF53 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x114C DUP2 DUP7 PUSH2 0xF53 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1160 DUP2 DUP6 PUSH2 0xC29 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x1174 DUP2 DUP5 PUSH2 0xC29 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x119D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x11BC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1237 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x121F JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0xECA JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 SWAP13 0xf7 SIGNEXTEND DIV 0xb7 0x5f 0xc2 RETURNDATACOPY PUSH8 0x62AE4C6C8F25CCAD 0x25 0xdf 0xcb CODECOPY 0xcf SAR 0xd3 SWAP7 PUSH15 0xB27CE513DE036C6578706572696D65 PUSH15 0x74616CF50037000000000000000000 ", + "sourceMap": "986:9378:28:-;;;1673:99;8:9:-1;5:2;;;30:1;27;20:12;5:2;1673:99:28;;;;;;;;;;;;;;;;;;;;;;1734:8;:31;;-1:-1:-1;;;;;;1734:31:28;-1:-1:-1;;;;;1734:31:28;;;;;;;;;;986:9378;;5:122:-1;;83:39;114:6;108:13;83:39;;;74:48;68:59;-1:-1;;;68:59;134:263;;249:2;237:9;228:7;224:23;220:32;217:2;;;265:1;262;255:12;217:2;300:1;317:64;373:7;353:9;317:64;;;307:74;211:186;-1:-1;;;;211:186;404:128;-1:-1;;;;;473:54;;456:76;;986:9378:28;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x60806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632e9cd03381146100505780633c28d86114610086575b600080fd5b34801561005c57600080fd5b5061007061006b366004610b25565b6100b3565b60405161007d919061110a565b60405180910390f35b34801561009257600080fd5b506100a66100a1366004610b5a565b61029c565b60405161007d9190611118565b6100bb6107b1565b610140820151516000808080808080606488101561010e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110aa565b60405180910390fd5b6101408a0151610146907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a0163ffffffff6105f216565b6101408b0151909750610181907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a0163ffffffff6105f216565b9550868a61010001511115156101c3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110ba565b868a61010001510394508960a001519350838611151561020f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110fa565b50505083865261010087018051602088015260408701849052606087018290524260a088018190529051828503919081900386821015610255576080890186905261028f565b6101008a0151821061026d576080890184905261028f565b6102898461028461027e8487610607565b8861066d565b610684565b60808a01525b5050505050505050919050565b6102a46107e8565b6102ac6107b1565b6000606060008060006102be8a6100b3565b805160a08201519197501115610300576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110ea565b60a08601516101008b015111610342576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110ca565b608080870151908c01511015610384576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110fa565b6000546040517f3c28d86100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633c28d861906103e0908e908e908e908e90600401611127565b61012060405180830381600087803b1580156103fb57600080fd5b505af115801561040f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104339190810190610b06565b96508660400151945060008511156105e4576101608a0151935061045e84601063ffffffff6106c316565b92506104728b608001518760800151610724565b915061047e8583610724565b905060008111156105325789516040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169163a9059cbb916104de9190859060040161105f565b602060405180830381600087803b1580156104f857600080fd5b505af115801561050c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105309190810190610ae0565b505b60008211156105e4578a516040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169163a9059cbb916105909190869060040161105f565b602060405180830381600087803b1580156105aa57600080fd5b505af11580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105e29190810190610ae0565b505b505050505050949350505050565b60006105fe8383610766565b90505b92915050565b60008083151561061a5760009150610666565b5082820282848281151561062a57fe5b0414610662576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061109a565b8091505b5092915050565b600080828481151561067b57fe5b04949350505050565b600082820183811015610662576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061109a565b600081601401835110151515610705576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610105906110da565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b600082821115610760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061107a565b50900390565b6000816020018351101515156107a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101059061108a565b50016020015190565b60c0604051908101604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b610120604051908101604052806107fd610817565b815260200161080a610817565b8152602001600081525090565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b600061084c82356111ef565b9392505050565b600061084c825161120b565b6000601f8201831361087057600080fd5b813561088361087e826111a5565b61117e565b9150808252602083016020830185838301111561089f57600080fd5b6108aa838284611210565b50505092915050565b6000608082840312156108c557600080fd5b6108cf608061117e565b905060006108dd8484610ad4565b82525060206108ee84848301610ad4565b602083015250604061090284828501610ad4565b604083015250606061091684828501610ad4565b60608301525092915050565b6000610120828403121561093557600080fd5b61093f606061117e565b9050600061094d84846108b3565b825250608061095e848483016108b3565b60208301525061010061097384828501610ad4565b60408301525092915050565b6000610180828403121561099257600080fd5b61099d61018061117e565b905060006109ab8484610840565b82525060206109bc84848301610840565b60208301525060406109d084828501610840565b60408301525060606109e484828501610840565b60608301525060806109f884828501610ac8565b60808301525060a0610a0c84828501610ac8565b60a08301525060c0610a2084828501610ac8565b60c08301525060e0610a3484828501610ac8565b60e083015250610100610a4984828501610ac8565b61010083015250610120610a5f84828501610ac8565b6101208301525061014082013567ffffffffffffffff811115610a8157600080fd5b610a8d8482850161085f565b6101408301525061016082013567ffffffffffffffff811115610aaf57600080fd5b610abb8482850161085f565b6101608301525092915050565b600061084c8235611208565b600061084c8251611208565b600060208284031215610af257600080fd5b6000610afe8484610853565b949350505050565b60006101208284031215610b1957600080fd5b6000610afe8484610922565b600060208284031215610b3757600080fd5b813567ffffffffffffffff811115610b4e57600080fd5b610afe8482850161097f565b60008060008060808587031215610b7057600080fd5b843567ffffffffffffffff811115610b8757600080fd5b610b938782880161097f565b945050602085013567ffffffffffffffff811115610bb057600080fd5b610bbc8782880161097f565b935050604085013567ffffffffffffffff811115610bd957600080fd5b610be58782880161085f565b925050606085013567ffffffffffffffff811115610c0257600080fd5b610c0e8782880161085f565b91505092959194509250565b610c23816111ef565b82525050565b6000610c34826111eb565b808452610c4881602086016020860161121c565b610c5181611248565b9093016020019392505050565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601281527f494e56414c49445f41535345545f444154410000000000000000000000000000602082015260400190565b601281527f494e56414c49445f424547494e5f54494d450000000000000000000000000000602082015260400190565b600f81527f41554354494f4e5f455850495245440000000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601381527f41554354494f4e5f4e4f545f5354415254454400000000000000000000000000602082015260400190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160c0830190610e6b8482611056565b506020820151610e7e6020850182611056565b506040820151610e916040850182611056565b506060820151610ea46060850182611056565b506080820151610eb76080850182611056565b5060a0820151610eca60a0850182611056565b50505050565b80516080830190610ee18482611056565b506020820151610ef46020850182611056565b506040820151610f076040850182611056565b506060820151610eca6060850182611056565b8051610120830190610f2c8482610ed0565b506020820151610f3f6080850182610ed0565b506040820151610eca610100850182611056565b8051600090610180840190610f688582610c1a565b506020830151610f7b6020860182610c1a565b506040830151610f8e6040860182610c1a565b506060830151610fa16060860182610c1a565b506080830151610fb46080860182611056565b5060a0830151610fc760a0860182611056565b5060c0830151610fda60c0860182611056565b5060e0830151610fed60e0860182611056565b50610100830151611002610100860182611056565b50610120830151611017610120860182611056565b506101408301518482036101408601526110318282610c29565b91505061016083015184820361016086015261104d8282610c29565b95945050505050565b610c2381611208565b6040810161106d8285610c1a565b61084c6020830184611056565b6020808252810161060181610c5e565b6020808252810161060181610c8e565b6020808252810161060181610ce4565b6020808252810161060181610d14565b6020808252810161060181610d44565b6020808252810161060181610d74565b6020808252810161060181610da4565b6020808252810161060181610dfa565b6020808252810161060181610e2a565b60c081016106018284610e5a565b61012081016106018284610f1a565b608080825281016111388187610f53565b9050818103602083015261114c8186610f53565b905081810360408301526111608185610c29565b905081810360608301526111748184610c29565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561119d57600080fd5b604052919050565b600067ffffffffffffffff8211156111bc57600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b151590565b82818337506000910152565b60005b8381101561123757818101518382015260200161121f565b83811115610eca5750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a723058209cf70b04b75fc23e6762ae4c6c8f25ccad25dfcb39cf1dd3966eb27ce513de036c6578706572696d656e74616cf50037", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4B JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x2E9CD033 DUP2 EQ PUSH2 0x50 JUMPI DUP1 PUSH4 0x3C28D861 EQ PUSH2 0x86 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x70 PUSH2 0x6B CALLDATASIZE PUSH1 0x4 PUSH2 0xB25 JUMP JUMPDEST PUSH2 0xB3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x7D SWAP2 SWAP1 PUSH2 0x110A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x92 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA6 PUSH2 0xA1 CALLDATASIZE PUSH1 0x4 PUSH2 0xB5A JUMP JUMPDEST PUSH2 0x29C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x7D SWAP2 SWAP1 PUSH2 0x1118 JUMP JUMPDEST PUSH2 0xBB PUSH2 0x7B1 JUMP JUMPDEST PUSH2 0x140 DUP3 ADD MLOAD MLOAD PUSH1 0x0 DUP1 DUP1 DUP1 DUP1 DUP1 DUP1 PUSH1 0x64 DUP9 LT ISZERO PUSH2 0x10E JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10AA JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x140 DUP11 ADD MLOAD PUSH2 0x146 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 DUP11 ADD PUSH4 0xFFFFFFFF PUSH2 0x5F2 AND JUMP JUMPDEST PUSH2 0x140 DUP12 ADD MLOAD SWAP1 SWAP8 POP PUSH2 0x181 SWAP1 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP11 ADD PUSH4 0xFFFFFFFF PUSH2 0x5F2 AND JUMP JUMPDEST SWAP6 POP DUP7 DUP11 PUSH2 0x100 ADD MLOAD GT ISZERO ISZERO PUSH2 0x1C3 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10BA JUMP JUMPDEST DUP7 DUP11 PUSH2 0x100 ADD MLOAD SUB SWAP5 POP DUP10 PUSH1 0xA0 ADD MLOAD SWAP4 POP DUP4 DUP7 GT ISZERO ISZERO PUSH2 0x20F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10FA JUMP JUMPDEST POP POP POP DUP4 DUP7 MSTORE PUSH2 0x100 DUP8 ADD DUP1 MLOAD PUSH1 0x20 DUP9 ADD MSTORE PUSH1 0x40 DUP8 ADD DUP5 SWAP1 MSTORE PUSH1 0x60 DUP8 ADD DUP3 SWAP1 MSTORE TIMESTAMP PUSH1 0xA0 DUP9 ADD DUP2 SWAP1 MSTORE SWAP1 MLOAD DUP3 DUP6 SUB SWAP2 SWAP1 DUP2 SWAP1 SUB DUP7 DUP3 LT ISZERO PUSH2 0x255 JUMPI PUSH1 0x80 DUP10 ADD DUP7 SWAP1 MSTORE PUSH2 0x28F JUMP JUMPDEST PUSH2 0x100 DUP11 ADD MLOAD DUP3 LT PUSH2 0x26D JUMPI PUSH1 0x80 DUP10 ADD DUP5 SWAP1 MSTORE PUSH2 0x28F JUMP JUMPDEST PUSH2 0x289 DUP5 PUSH2 0x284 PUSH2 0x27E DUP5 DUP8 PUSH2 0x607 JUMP JUMPDEST DUP9 PUSH2 0x66D JUMP JUMPDEST PUSH2 0x684 JUMP JUMPDEST PUSH1 0x80 DUP11 ADD MSTORE JUMPDEST POP POP POP POP POP POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2A4 PUSH2 0x7E8 JUMP JUMPDEST PUSH2 0x2AC PUSH2 0x7B1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x2BE DUP11 PUSH2 0xB3 JUMP JUMPDEST DUP1 MLOAD PUSH1 0xA0 DUP3 ADD MLOAD SWAP2 SWAP8 POP GT ISZERO PUSH2 0x300 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10EA JUMP JUMPDEST PUSH1 0xA0 DUP7 ADD MLOAD PUSH2 0x100 DUP12 ADD MLOAD GT PUSH2 0x342 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10CA JUMP JUMPDEST PUSH1 0x80 DUP1 DUP8 ADD MLOAD SWAP1 DUP13 ADD MLOAD LT ISZERO PUSH2 0x384 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10FA JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH1 0x40 MLOAD PUSH32 0x3C28D86100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND SWAP1 PUSH4 0x3C28D861 SWAP1 PUSH2 0x3E0 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 DUP15 SWAP1 PUSH1 0x4 ADD PUSH2 0x1127 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x3FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x40F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x433 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0xB06 JUMP JUMPDEST SWAP7 POP DUP7 PUSH1 0x40 ADD MLOAD SWAP5 POP PUSH1 0x0 DUP6 GT ISZERO PUSH2 0x5E4 JUMPI PUSH2 0x160 DUP11 ADD MLOAD SWAP4 POP PUSH2 0x45E DUP5 PUSH1 0x10 PUSH4 0xFFFFFFFF PUSH2 0x6C3 AND JUMP JUMPDEST SWAP3 POP PUSH2 0x472 DUP12 PUSH1 0x80 ADD MLOAD DUP8 PUSH1 0x80 ADD MLOAD PUSH2 0x724 JUMP JUMPDEST SWAP2 POP PUSH2 0x47E DUP6 DUP4 PUSH2 0x724 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 GT ISZERO PUSH2 0x532 JUMPI DUP10 MLOAD PUSH1 0x40 MLOAD PUSH32 0xA9059CBB00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP2 PUSH4 0xA9059CBB SWAP2 PUSH2 0x4DE SWAP2 SWAP1 DUP6 SWAP1 PUSH1 0x4 ADD PUSH2 0x105F JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x4F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x50C JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x530 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0xAE0 JUMP JUMPDEST POP JUMPDEST PUSH1 0x0 DUP3 GT ISZERO PUSH2 0x5E4 JUMPI DUP11 MLOAD PUSH1 0x40 MLOAD PUSH32 0xA9059CBB00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND SWAP2 PUSH4 0xA9059CBB SWAP2 PUSH2 0x590 SWAP2 SWAP1 DUP7 SWAP1 PUSH1 0x4 ADD PUSH2 0x105F JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x5AA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x5BE JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP PUSH2 0x5E2 SWAP2 SWAP1 DUP2 ADD SWAP1 PUSH2 0xAE0 JUMP JUMPDEST POP JUMPDEST POP POP POP POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x5FE DUP4 DUP4 PUSH2 0x766 JUMP JUMPDEST SWAP1 POP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 ISZERO ISZERO PUSH2 0x61A JUMPI PUSH1 0x0 SWAP2 POP PUSH2 0x666 JUMP JUMPDEST POP DUP3 DUP3 MUL DUP3 DUP5 DUP3 DUP2 ISZERO ISZERO PUSH2 0x62A JUMPI INVALID JUMPDEST DIV EQ PUSH2 0x662 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x109A JUMP JUMPDEST DUP1 SWAP2 POP JUMPDEST POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 DUP2 ISZERO ISZERO PUSH2 0x67B JUMPI INVALID JUMPDEST DIV SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 ADD DUP4 DUP2 LT ISZERO PUSH2 0x662 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x109A JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x14 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x705 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x10DA JUMP JUMPDEST POP ADD PUSH1 0x14 ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 GT ISZERO PUSH2 0x760 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x107A JUMP JUMPDEST POP SWAP1 SUB SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x20 ADD DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x7A8 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x105 SWAP1 PUSH2 0x108A JUMP JUMPDEST POP ADD PUSH1 0x20 ADD MLOAD SWAP1 JUMP JUMPDEST PUSH1 0xC0 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH2 0x120 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH2 0x7FD PUSH2 0x817 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x80A PUSH2 0x817 JUMP JUMPDEST DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x80 PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 DUP2 MSTORE POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 CALLDATALOAD PUSH2 0x11EF JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 MLOAD PUSH2 0x120B JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F DUP3 ADD DUP4 SGT PUSH2 0x870 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x883 PUSH2 0x87E DUP3 PUSH2 0x11A5 JUMP JUMPDEST PUSH2 0x117E JUMP JUMPDEST SWAP2 POP DUP1 DUP3 MSTORE PUSH1 0x20 DUP4 ADD PUSH1 0x20 DUP4 ADD DUP6 DUP4 DUP4 ADD GT ISZERO PUSH2 0x89F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x8AA DUP4 DUP3 DUP5 PUSH2 0x1210 JUMP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x80 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x8C5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x8CF PUSH1 0x80 PUSH2 0x117E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x8DD DUP5 DUP5 PUSH2 0xAD4 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x8EE DUP5 DUP5 DUP4 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x902 DUP5 DUP3 DUP6 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x916 DUP5 DUP3 DUP6 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x120 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x935 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x93F PUSH1 0x60 PUSH2 0x117E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x94D DUP5 DUP5 PUSH2 0x8B3 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x80 PUSH2 0x95E DUP5 DUP5 DUP4 ADD PUSH2 0x8B3 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0x973 DUP5 DUP3 DUP6 ADD PUSH2 0xAD4 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x180 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x992 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x99D PUSH2 0x180 PUSH2 0x117E JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0x9AB DUP5 DUP5 PUSH2 0x840 JUMP JUMPDEST DUP3 MSTORE POP PUSH1 0x20 PUSH2 0x9BC DUP5 DUP5 DUP4 ADD PUSH2 0x840 JUMP JUMPDEST PUSH1 0x20 DUP4 ADD MSTORE POP PUSH1 0x40 PUSH2 0x9D0 DUP5 DUP3 DUP6 ADD PUSH2 0x840 JUMP JUMPDEST PUSH1 0x40 DUP4 ADD MSTORE POP PUSH1 0x60 PUSH2 0x9E4 DUP5 DUP3 DUP6 ADD PUSH2 0x840 JUMP JUMPDEST PUSH1 0x60 DUP4 ADD MSTORE POP PUSH1 0x80 PUSH2 0x9F8 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0x80 DUP4 ADD MSTORE POP PUSH1 0xA0 PUSH2 0xA0C DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0xA0 DUP4 ADD MSTORE POP PUSH1 0xC0 PUSH2 0xA20 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0xC0 DUP4 ADD MSTORE POP PUSH1 0xE0 PUSH2 0xA34 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH1 0xE0 DUP4 ADD MSTORE POP PUSH2 0x100 PUSH2 0xA49 DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH2 0x100 DUP4 ADD MSTORE POP PUSH2 0x120 PUSH2 0xA5F DUP5 DUP3 DUP6 ADD PUSH2 0xAC8 JUMP JUMPDEST PUSH2 0x120 DUP4 ADD MSTORE POP PUSH2 0x140 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xA81 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA8D DUP5 DUP3 DUP6 ADD PUSH2 0x85F JUMP JUMPDEST PUSH2 0x140 DUP4 ADD MSTORE POP PUSH2 0x160 DUP3 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xAAF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xABB DUP5 DUP3 DUP6 ADD PUSH2 0x85F JUMP JUMPDEST PUSH2 0x160 DUP4 ADD MSTORE POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 CALLDATALOAD PUSH2 0x1208 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x84C DUP3 MLOAD PUSH2 0x1208 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xAF2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAFE DUP5 DUP5 PUSH2 0x853 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x120 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB19 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0xAFE DUP5 DUP5 PUSH2 0x922 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB37 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xAFE DUP5 DUP3 DUP6 ADD PUSH2 0x97F JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB70 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB87 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB93 DUP8 DUP3 DUP9 ADD PUSH2 0x97F JUMP JUMPDEST SWAP5 POP POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBB0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBBC DUP8 DUP3 DUP9 ADD PUSH2 0x97F JUMP JUMPDEST SWAP4 POP POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBD9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBE5 DUP8 DUP3 DUP9 ADD PUSH2 0x85F JUMP JUMPDEST SWAP3 POP POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC02 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC0E DUP8 DUP3 DUP9 ADD PUSH2 0x85F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH2 0xC23 DUP2 PUSH2 0x11EF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xC34 DUP3 PUSH2 0x11EB JUMP JUMPDEST DUP1 DUP5 MSTORE PUSH2 0xC48 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x121C JUMP JUMPDEST PUSH2 0xC51 DUP2 PUSH2 0x1248 JUMP JUMPDEST SWAP1 SWAP4 ADD PUSH1 0x20 ADD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x11 DUP2 MSTORE PUSH32 0x55494E543235365F554E444552464C4F57000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F33325F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x10 DUP2 MSTORE PUSH32 0x55494E543235365F4F564552464C4F5700000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x494E56414C49445F41535345545F444154410000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x12 DUP2 MSTORE PUSH32 0x494E56414C49445F424547494E5F54494D450000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xF DUP2 MSTORE PUSH32 0x41554354494F4E5F455850495245440000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x26 DUP2 MSTORE PUSH32 0x475245415445525F4F525F455155414C5F544F5F32305F4C454E4754485F5245 PUSH1 0x20 DUP3 ADD MSTORE PUSH32 0x5155495245440000000000000000000000000000000000000000000000000000 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x60 ADD SWAP1 JUMP JUMPDEST PUSH1 0x13 DUP2 MSTORE PUSH32 0x41554354494F4E5F4E4F545F5354415254454400000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0xE DUP2 MSTORE PUSH32 0x494E56414C49445F414D4F554E54000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST DUP1 MLOAD PUSH1 0xC0 DUP4 ADD SWAP1 PUSH2 0xE6B DUP5 DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0xE7E PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0xE91 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0xEA4 PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x80 DUP3 ADD MLOAD PUSH2 0xEB7 PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xA0 DUP3 ADD MLOAD PUSH2 0xECA PUSH1 0xA0 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST DUP1 MLOAD PUSH1 0x80 DUP4 ADD SWAP1 PUSH2 0xEE1 DUP5 DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0xEF4 PUSH1 0x20 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0xF07 PUSH1 0x40 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0x60 DUP3 ADD MLOAD PUSH2 0xECA PUSH1 0x60 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST DUP1 MLOAD PUSH2 0x120 DUP4 ADD SWAP1 PUSH2 0xF2C DUP5 DUP3 PUSH2 0xED0 JUMP JUMPDEST POP PUSH1 0x20 DUP3 ADD MLOAD PUSH2 0xF3F PUSH1 0x80 DUP6 ADD DUP3 PUSH2 0xED0 JUMP JUMPDEST POP PUSH1 0x40 DUP3 ADD MLOAD PUSH2 0xECA PUSH2 0x100 DUP6 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST DUP1 MLOAD PUSH1 0x0 SWAP1 PUSH2 0x180 DUP5 ADD SWAP1 PUSH2 0xF68 DUP6 DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x20 DUP4 ADD MLOAD PUSH2 0xF7B PUSH1 0x20 DUP7 ADD DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x40 DUP4 ADD MLOAD PUSH2 0xF8E PUSH1 0x40 DUP7 ADD DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x60 DUP4 ADD MLOAD PUSH2 0xFA1 PUSH1 0x60 DUP7 ADD DUP3 PUSH2 0xC1A JUMP JUMPDEST POP PUSH1 0x80 DUP4 ADD MLOAD PUSH2 0xFB4 PUSH1 0x80 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xA0 DUP4 ADD MLOAD PUSH2 0xFC7 PUSH1 0xA0 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xC0 DUP4 ADD MLOAD PUSH2 0xFDA PUSH1 0xC0 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH1 0xE0 DUP4 ADD MLOAD PUSH2 0xFED PUSH1 0xE0 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH2 0x100 DUP4 ADD MLOAD PUSH2 0x1002 PUSH2 0x100 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH2 0x120 DUP4 ADD MLOAD PUSH2 0x1017 PUSH2 0x120 DUP7 ADD DUP3 PUSH2 0x1056 JUMP JUMPDEST POP PUSH2 0x140 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x140 DUP7 ADD MSTORE PUSH2 0x1031 DUP3 DUP3 PUSH2 0xC29 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x160 DUP4 ADD MLOAD DUP5 DUP3 SUB PUSH2 0x160 DUP7 ADD MSTORE PUSH2 0x104D DUP3 DUP3 PUSH2 0xC29 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0xC23 DUP2 PUSH2 0x1208 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD PUSH2 0x106D DUP3 DUP6 PUSH2 0xC1A JUMP JUMPDEST PUSH2 0x84C PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1056 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xC5E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xC8E JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xCE4 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xD14 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xD44 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xD74 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xDA4 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xDFA JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x601 DUP2 PUSH2 0xE2A JUMP JUMPDEST PUSH1 0xC0 DUP2 ADD PUSH2 0x601 DUP3 DUP5 PUSH2 0xE5A JUMP JUMPDEST PUSH2 0x120 DUP2 ADD PUSH2 0x601 DUP3 DUP5 PUSH2 0xF1A JUMP JUMPDEST PUSH1 0x80 DUP1 DUP3 MSTORE DUP2 ADD PUSH2 0x1138 DUP2 DUP8 PUSH2 0xF53 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x114C DUP2 DUP7 PUSH2 0xF53 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x40 DUP4 ADD MSTORE PUSH2 0x1160 DUP2 DUP6 PUSH2 0xC29 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x60 DUP4 ADD MSTORE PUSH2 0x1174 DUP2 DUP5 PUSH2 0xC29 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD DUP2 DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0x119D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x11BC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x20 PUSH1 0x1F SWAP2 SWAP1 SWAP2 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD SWAP1 JUMP JUMPDEST MLOAD SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST ISZERO ISZERO SWAP1 JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1237 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0x121F JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0xECA JUMPI POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x1F ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND SWAP1 JUMP STOP LOG2 PUSH6 0x627A7A723058 KECCAK256 SWAP13 0xf7 SIGNEXTEND DIV 0xb7 0x5f 0xc2 RETURNDATACOPY PUSH8 0x62AE4C6C8F25CCAD 0x25 0xdf 0xcb CODECOPY 0xcf SAR 0xd3 SWAP7 PUSH15 0xB27CE513DE036C6578706572696D65 PUSH15 0x74616CF50037000000000000000000 ", + "sourceMap": "986:9378:28:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;7335:3027;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7335:3027:28;;;;;;;;;;;;;;;;;;;;;;;;;3690:3508;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3690:3508:28;;;;;;;;;;;;;;;;;7335:3027;7437:36;;:::i;:::-;7520:20;;;;:27;7489:28;;;;;;;8295:3;8271:27;;;8250:92;;;;;;;;;;;;;;;;;;;;;;8386:20;;;;:59;;8419:25;;;8386:59;:32;:59;:::i;:::-;8484:20;;;;8352:93;;-1:-1:-1;8484:59:28;;8517:25;;;8484:59;:32;:59;:::i;:::-;8455:88;;8657:23;8627:5;:27;;;:53;8606:118;;;;;;;;;;;;;;;;8795:23;8767:5;:27;;;:51;8734:84;;8900:5;:22;;;8880:42;;8974:9;8953:18;:30;8932:91;;;;;;;;;;;;;;;;-1:-1:-1;;;9192:57:28;;;9291:27;;;;;9259:29;;;:59;9328:26;;;:47;;;9385:24;;;:36;;;9167:15;9431:33;;;:45;;;9522:27;;9055:28;;;;9167:15;9522:37;;;9573:35;;;9569:756;;;9717:28;;;:49;;;9569:756;;;9800:27;;;;9787:40;;9783:542;;10009:28;;;:40;;;9783:542;;;10111:203;10136:9;10163:137;10192:46;10200:24;10226:11;10192:7;:46::i;:::-;10260:22;10163:7;:137::i;:::-;10111:7;:203::i;:::-;10080:28;;;:234;9783:542;7335:3027;;;;;;;;;;;:::o;3690:3508::-;3901:59;;:::i;:::-;3976:36;;:::i;:::-;5398:34;6127:22;6190:13;6404:25;6510:26;4015:28;4033:9;4015:17;:28::i;:::-;4161:31;;4124:33;;;;3976:67;;-1:-1:-1;;4124:68:28;4103:134;;;;;;;;;;;;;;4413:33;;;;4379:31;;;;:67;4358:129;;;;;;;;;;;;;;4627:28;;;;;4598:25;;;;:57;;4577:118;;;;;;;;;;;;;;4780:8;;:128;;;;;:8;;;;;:20;;:128;;4814:8;;4836:9;;4859:12;;4885:13;;4780:128;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4780:128:28;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;4780:128:28;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;4780:128:28;;;;;;;;;4759:149;;5435:18;:45;;;5398:82;;5523:1;5494:26;:30;5490:1667;;;6152:24;;;;;-1:-1:-1;6206:25:28;6152:24;6228:2;6206:25;:21;:25;:::i;:::-;6190:41;;6432:64;6440:8;:25;;;6467:14;:28;;;6432:7;:64::i;:::-;6404:92;;6539:54;6547:26;6575:17;6539:7;:54::i;:::-;6510:83;;6766:1;6745:18;:22;6741:132;;;6815:22;;6787:71;;;;;:27;;;;;;:71;;6815:22;6839:18;;6787:71;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6787:71:28;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6787:71:28;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6787:71:28;;;;;;;;;;6741:132;7042:1;7022:17;:21;7018:129;;;7091:21;;7063:69;;;;;:27;;;;;;:69;;7091:21;7114:17;;7063:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7063:69:28;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7063:69:28;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;7063:69:28;;;;;;;;;;7018:129;3690:3508;;;;;;;;;;;;:::o;14708:220:17:-;14829:14;14876:21;14888:1;14891:5;14876:11;:21::i;:::-;14868:30;-1:-1:-1;14708:220:17;;;;;:::o;51:288:20:-;137:7;;164:6;;160:45;;;193:1;186:8;;;;160:45;-1:-1:-1;226:5:20;;;230:1;226;:5;262;;;;;;;;:10;241:73;;;;;;;;;;;;;;331:1;324:8;;51:288;;;;;;:::o;345:151::-;431:7;454:9;470:1;466;:5;;;;;;;;;345:151;-1:-1:-1;;;;345:151:20:o;716:230::-;802:7;837:5;;;873:6;;;;852:69;;;;;;;;;;;;;10268:886:17;10389:14;10452:5;10460:2;10452:10;10440:1;:8;:22;;10419:135;;;;;;;;;;;;;;;;-1:-1:-1;11056:13:17;10801:2;11056:13;11050:20;11072:42;11046:69;;10268:886::o;502:208:20:-;588:7;632:6;;;;611:70;;;;;;;;;;;;;;-1:-1:-1;698:5:20;;;502:208::o;13290:490:17:-;13411:14;13474:5;13482:2;13474:10;13462:1;:8;:22;;13441:107;;;;;;;;;;;;;;;;-1:-1:-1;13727:13:17;13629:2;13727:13;13721:20;;13290:490::o;986:9378:28:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:118:-1:-;;72:46;110:6;97:20;72:46;;;63:55;57:66;-1:-1;;;57:66;130:116;;205:36;233:6;227:13;205:36;;254:432;;344:4;332:17;;328:27;-1:-1;318:2;;369:1;366;359:12;318:2;406:6;393:20;428:60;443:44;480:6;443:44;;;428:60;;;419:69;;508:6;501:5;494:21;544:4;536:6;532:17;577:4;570:5;566:16;612:3;603:6;598:3;594:16;591:25;588:2;;;629:1;626;619:12;588:2;639:41;673:6;668:3;663;639:41;;;311:375;;;;;;;;1183:861;;1308:4;1296:9;1291:3;1287:19;1283:30;1280:2;;;1326:1;1323;1316:12;1280:2;1344:20;1359:4;1344:20;;;1335:29;-1:-1;1432:1;1463:60;1519:3;1499:9;1463:60;;;1439:85;;-1:-1;1603:2;1636:60;1692:3;1668:22;;;1636:60;;;1629:4;1622:5;1618:16;1611:86;1545:163;1766:2;1799:60;1855:3;1846:6;1835:9;1831:22;1799:60;;;1792:4;1785:5;1781:16;1774:86;1718:153;1929:2;1962:60;2018:3;2009:6;1998:9;1994:22;1962:60;;;1955:4;1948:5;1944:16;1937:86;1881:153;1274:770;;;;;2098:741;;2234:5;2222:9;2217:3;2213:19;2209:31;2206:2;;;2253:1;2250;2243:12;2206:2;2271:20;2286:4;2271:20;;;2262:29;-1:-1;2341:1;2372:85;2453:3;2433:9;2372:85;;;2348:110;;-1:-1;2520:3;2554:85;2635:3;2611:22;;;2554:85;;;2547:4;2540:5;2536:16;2529:111;2479:172;2723:3;2757:60;2813:3;2804:6;2793:9;2789:22;2757:60;;;2750:4;2743:5;2739:16;2732:86;2661:168;2200:639;;;;;2874:2208;;2985:5;2973:9;2968:3;2964:19;2960:31;2957:2;;;3004:1;3001;2994:12;2957:2;3022:21;3037:5;3022:21;;;3013:30;-1:-1;3101:1;3132:49;3177:3;3157:9;3132:49;;;3108:74;;-1:-1;3251:2;3284:49;3329:3;3305:22;;;3284:49;;;3277:4;3270:5;3266:16;3259:75;3203:142;3410:2;3443:49;3488:3;3479:6;3468:9;3464:22;3443:49;;;3436:4;3429:5;3425:16;3418:75;3355:149;3563:2;3596:49;3641:3;3632:6;3621:9;3617:22;3596:49;;;3589:4;3582:5;3578:16;3571:75;3514:143;3719:3;3753:49;3798:3;3789:6;3778:9;3774:22;3753:49;;;3746:4;3739:5;3735:16;3728:75;3667:147;3876:3;3910:49;3955:3;3946:6;3935:9;3931:22;3910:49;;;3903:4;3896:5;3892:16;3885:75;3824:147;4025:3;4059:49;4104:3;4095:6;4084:9;4080:22;4059:49;;;4052:4;4045:5;4041:16;4034:75;3981:139;4174:3;4208:49;4253:3;4244:6;4233:9;4229:22;4208:49;;;4201:4;4194:5;4190:16;4183:75;4130:139;4336:3;4371:49;4416:3;4407:6;4396:9;4392:22;4371:49;;;4363:5;4356;4352:17;4345:76;4279:153;4482:3;4517:49;4562:3;4553:6;4542:9;4538:22;4517:49;;;4509:5;4502;4498:17;4491:76;4442:136;4666:3;4655:9;4651:19;4638:33;4691:18;4683:6;4680:30;4677:2;;;4723:1;4720;4713:12;4677:2;4759:54;4809:3;4800:6;4789:9;4785:22;4759:54;;;4751:5;4744;4740:17;4733:81;4588:237;4913:3;4902:9;4898:19;4885:33;4938:18;4930:6;4927:30;4924:2;;;4970:1;4967;4960:12;4924:2;5006:54;5056:3;5047:6;5036:9;5032:22;5006:54;;;4998:5;4991;4987:17;4980:81;4835:237;2951:2131;;;;;5089:118;;5156:46;5194:6;5181:20;5156:46;;5214:122;;5292:39;5323:6;5317:13;5292:39;;5343:257;;5455:2;5443:9;5434:7;5430:23;5426:32;5423:2;;;5471:1;5468;5461:12;5423:2;5506:1;5523:61;5576:7;5556:9;5523:61;;;5513:71;5417:183;-1:-1;;;;5417:183;5607:336;;5758:3;5746:9;5737:7;5733:23;5729:33;5726:2;;;5775:1;5772;5765:12;5726:2;5810:1;5827:100;5919:7;5899:9;5827:100;;5950:371;;6076:2;6064:9;6055:7;6051:23;6047:32;6044:2;;;6092:1;6089;6082:12;6044:2;6127:31;;6178:18;6167:30;;6164:2;;;6210:1;6207;6200:12;6164:2;6230:75;6297:7;6288:6;6277:9;6273:22;6230:75;;6328:1085;;;;;6545:3;6533:9;6524:7;6520:23;6516:33;6513:2;;;6562:1;6559;6552:12;6513:2;6597:31;;6648:18;6637:30;;6634:2;;;6680:1;6677;6670:12;6634:2;6700:75;6767:7;6758:6;6747:9;6743:22;6700:75;;;6690:85;;6576:205;6840:2;6829:9;6825:18;6812:32;6864:18;6856:6;6853:30;6850:2;;;6896:1;6893;6886:12;6850:2;6916:75;6983:7;6974:6;6963:9;6959:22;6916:75;;;6906:85;;6791:206;7056:2;7045:9;7041:18;7028:32;7080:18;7072:6;7069:30;7066:2;;;7112:1;7109;7102:12;7066:2;7132:62;7186:7;7177:6;7166:9;7162:22;7132:62;;;7122:72;;7007:193;7259:2;7248:9;7244:18;7231:32;7283:18;7275:6;7272:30;7269:2;;;7315:1;7312;7305:12;7269:2;7335:62;7389:7;7380:6;7369:9;7365:22;7335:62;;;7325:72;;7210:193;6507:906;;;;;;;;7420:110;7493:31;7518:5;7493:31;;;7488:3;7481:44;7475:55;;;7537:297;;7637:38;7669:5;7637:38;;;7692:6;7687:3;7680:19;7704:63;7760:6;7753:4;7748:3;7744:14;7737:4;7730:5;7726:16;7704:63;;;7799:29;7821:6;7799:29;;;7779:50;;;7792:4;7779:50;;7617:217;-1:-1;;;7617:217;8138:296;8293:2;8281:15;;8330:66;8325:2;8316:12;;8309:88;8425:2;8416:12;;8274:160;8443:397;8598:2;8586:15;;8635:66;8630:2;8621:12;;8614:88;8736:66;8731:2;8722:12;;8715:88;8831:2;8822:12;;8579:261;8849:296;9004:2;8992:15;;9041:66;9036:2;9027:12;;9020:88;9136:2;9127:12;;8985:160;9154:296;9309:2;9297:15;;9346:66;9341:2;9332:12;;9325:88;9441:2;9432:12;;9290:160;9459:296;9614:2;9602:15;;9651:66;9646:2;9637:12;;9630:88;9746:2;9737:12;;9595:160;9764:296;9919:2;9907:15;;9956:66;9951:2;9942:12;;9935:88;10051:2;10042:12;;9900:160;10069:397;10224:2;10212:15;;10261:66;10256:2;10247:12;;10240:88;10362:66;10357:2;10348:12;;10341:88;10457:2;10448:12;;10205:261;10475:296;10630:2;10618:15;;10667:66;10662:2;10653:12;;10646:88;10762:2;10753:12;;10611:160;10780:296;10935:2;10923:15;;10972:66;10967:2;10958:12;;10951:88;11067:2;11058:12;;10916:160;11163:1231;11387:22;;11306:4;11297:14;;;11421:61;11301:3;11387:22;11421:61;;;11326:168;11580:4;11573:5;11569:16;11563:23;11598:62;11654:4;11649:3;11645:14;11632:11;11598:62;;;11504:168;11755:4;11748:5;11744:16;11738:23;11773:62;11829:4;11824:3;11820:14;11807:11;11773:62;;;11682:165;11928:4;11921:5;11917:16;11911:23;11946:62;12002:4;11997:3;11993:14;11980:11;11946:62;;;11857:163;12105:4;12098:5;12094:16;12088:23;12123:62;12179:4;12174:3;12170:14;12157:11;12123:62;;;12030:167;12287:4;12280:5;12276:16;12270:23;12305:62;12361:4;12356:3;12352:14;12339:11;12305:62;;;12207:172;11279:1115;;;;12478:884;12702:22;;12615:4;12606:14;;;12736:61;12610:3;12702:22;12736:61;;;12635:174;12903:4;12896:5;12892:16;12886:23;12921:62;12977:4;12972:3;12968:14;12955:11;12921:62;;;12819:176;13079:4;13072:5;13068:16;13062:23;13097:62;13153:4;13148:3;13144:14;13131:11;13097:62;;;13005:166;13255:4;13248:5;13244:16;13238:23;13273:62;13329:4;13324:3;13320:14;13307:11;13273:62;;13460:815;13685:22;;13615:5;13606:15;;;13719:115;13610:3;13685:22;13719:115;;;13636:210;13923:4;13916:5;13912:16;13906:23;13941:116;14051:4;14046:3;14042:14;14029:11;13941:116;;;13856:213;14167:4;14160:5;14156:16;14150:23;14185:63;14241:5;14236:3;14232:15;14219:11;14185:63;;14335:2417;14548:22;;14335:2417;;14470:5;14461:15;;;14582:61;14465:3;14548:22;14582:61;;;14491:164;14739:4;14732:5;14728:16;14722:23;14757:62;14813:4;14808:3;14804:14;14791:11;14757:62;;;14665:166;14922:4;14915:5;14911:16;14905:23;14940:62;14996:4;14991:3;14987:14;14974:11;14940:62;;;14841:173;15099:4;15092:5;15088:16;15082:23;15117:62;15173:4;15168:3;15164:14;15151:11;15117:62;;;15024:167;15279:4;15272:5;15268:16;15262:23;15297:62;15353:4;15348:3;15344:14;15331:11;15297:62;;;15201:170;15459:4;15452:5;15448:16;15442:23;15477:62;15533:4;15528:3;15524:14;15511:11;15477:62;;;15381:170;15631:4;15624:5;15620:16;15614:23;15649:62;15705:4;15700:3;15696:14;15683:11;15649:62;;;15561:162;15803:4;15796:5;15792:16;15786:23;15821:62;15877:4;15872:3;15868:14;15855:11;15821:62;;;15733:162;15988:5;15981;15977:17;15971:24;16007:63;16063:5;16058:3;16054:15;16041:11;16007:63;;;15905:177;16158:5;16151;16147:17;16141:24;16177:63;16233:5;16228:3;16224:15;16211:11;16177:63;;;16092:160;16338:5;16331;16327:17;16321:24;16391:3;16385:4;16381:14;16373:5;16368:3;16364:15;16357:39;16411:66;16472:4;16459:11;16411:66;;;16403:74;;16262:227;16575:5;16568;16564:17;16558:24;16628:3;16622:4;16618:14;16610:5;16605:3;16601:15;16594:39;16648:66;16709:4;16696:11;16648:66;;;16640:74;14443:2309;-1:-1;;;;;14443:2309;16759:110;16832:31;16857:5;16832:31;;16876:294;17012:2;16997:18;;17026:61;17001:9;17060:6;17026:61;;;17098:62;17156:2;17145:9;17141:18;17132:6;17098:62;;17177:387;17358:2;17372:47;;;17343:18;;17433:121;17343:18;17433:121;;17571:387;17752:2;17766:47;;;17737:18;;17827:121;17737:18;17827:121;;17965:387;18146:2;18160:47;;;18131:18;;18221:121;18131:18;18221:121;;18359:387;18540:2;18554:47;;;18525:18;;18615:121;18525:18;18615:121;;18753:387;18934:2;18948:47;;;18919:18;;19009:121;18919:18;19009:121;;19147:387;19328:2;19342:47;;;19313:18;;19403:121;19313:18;19403:121;;19541:387;19722:2;19736:47;;;19707:18;;19797:121;19707:18;19797:121;;19935:387;20116:2;20130:47;;;20101:18;;20191:121;20101:18;20191:121;;20329:387;20510:2;20524:47;;;20495:18;;20585:121;20495:18;20585:121;;20723:314;20891:3;20876:19;;20906:121;20880:9;21000:6;20906:121;;21044:338;21224:3;21209:19;;21239:133;21213:9;21345:6;21239:133;;21389:937;21705:3;21720:47;;;21690:19;;21781:92;21690:19;21859:6;21781:92;;;21773:100;;21921:9;21915:4;21911:20;21906:2;21895:9;21891:18;21884:48;21946:92;22033:4;22024:6;21946:92;;;21938:100;;22086:9;22080:4;22076:20;22071:2;22060:9;22056:18;22049:48;22111:66;22172:4;22163:6;22111:66;;;22103:74;;22225:9;22219:4;22215:20;22210:2;22199:9;22195:18;22188:48;22250:66;22311:4;22302:6;22250:66;;;22242:74;21676:650;-1:-1;;;;;;21676:650;22333:256;22395:2;22389:9;22421:17;;;22496:18;22481:34;;22517:22;;;22478:62;22475:2;;;22553:1;22550;22543:12;22475:2;22569;22562:22;22373:216;;-1:-1;22373:216;22596:254;;22735:18;22727:6;22724:30;22721:2;;;22767:1;22764;22757:12;22721:2;-1:-1;22840:4;22811;22788:17;;;;22807:9;22784:33;22830:15;;22658:192;23122:87;23192:12;;23176:33;23314:128;23394:42;23383:54;;23366:76;23449:79;23518:5;23501:27;23670:92;23743:13;23736:21;;23719:43;23856:145;23937:6;23932:3;23927;23914:30;-1:-1;23993:1;23975:16;;23968:27;23907:94;24010:268;24075:1;24082:101;24096:6;24093:1;24090:13;24082:101;;;24163:11;;;24157:18;24144:11;;;24137:39;24118:2;24111:10;24082:101;;;24198:6;24195:1;24192:13;24189:2;;;-1:-1;;24263:1;24245:16;;24238:27;24059:219;24286:97;24374:2;24354:14;24370:7;24350:28;;24334:49" + } + } + }, + "sources": { + "DutchAuction/DutchAuction.sol": { + "id": 28 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol": { + "id": 1 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchangeCore.sol": { + "id": 2 + }, + "@0x/contracts-libs/contracts/libs/LibOrder.sol": { + "id": 13 + }, + "@0x/contracts-libs/contracts/libs/LibEIP712.sol": { + "id": 9 + }, + "@0x/contracts-libs/contracts/libs/LibFillResults.sol": { + "id": 11 + }, + "@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol": { + "id": 20 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/IMatchOrders.sol": { + "id": 3 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/ISignatureValidator.sol": { + "id": 4 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/ITransactions.sol": { + "id": 5 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/IAssetProxyDispatcher.sol": { + "id": 0 + }, + "@0x/contracts-interfaces/contracts/protocol/Exchange/IWrapperFunctions.sol": { + "id": 6 + }, + "@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol": { + "id": 14 + }, + "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol": { + "id": 17 + } + }, + "sourceCodes": { + "DutchAuction/DutchAuction.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol\";\nimport \"@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol\";\nimport \"@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol\";\n\n\ncontract DutchAuction is\n SafeMath\n{\n using LibBytes for bytes;\n\n // solhint-disable var-name-mixedcase\n IExchange internal EXCHANGE;\n\n struct AuctionDetails {\n uint256 beginTimeSeconds; // Auction begin unix timestamp: sellOrder.makerAssetData\n uint256 endTimeSeconds; // Auction end unix timestamp: sellOrder.expiryTimeSeconds\n uint256 beginAmount; // Auction begin amount: sellOrder.makerAssetData\n uint256 endAmount; // Auction end amount: sellOrder.takerAssetAmount\n uint256 currentAmount; // Calculated amount given block.timestamp\n uint256 currentTimeSeconds; // block.timestamp\n }\n\n constructor (address _exchange)\n public\n {\n EXCHANGE = IExchange(_exchange);\n }\n\n /// @dev Matches the buy and sell orders at an amount given the following: the current block time, the auction\n /// start time and the auction begin amount. The sell order is a an order at the lowest amount\n /// at the end of the auction. Excess from the match is transferred to the seller.\n /// Over time the price moves from beginAmount to endAmount given the current block.timestamp.\n /// sellOrder.expiryTimeSeconds is the end time of the auction.\n /// sellOrder.takerAssetAmount is the end amount of the auction (lowest possible amount).\n /// sellOrder.makerAssetData is the ABI encoded Asset Proxy data with the following data appended\n /// buyOrder.makerAssetData is the buyers bid on the auction, must meet the amount for the current block timestamp\n /// (uint256 beginTimeSeconds, uint256 beginAmount).\n /// This function reverts in the following scenarios:\n /// * Auction has not started (auctionDetails.currentTimeSeconds < auctionDetails.beginTimeSeconds)\n /// * Auction has expired (auctionDetails.endTimeSeconds < auctionDetails.currentTimeSeconds)\n /// * Amount is invalid: Buy order amount is too low (buyOrder.makerAssetAmount < auctionDetails.currentAmount)\n /// * Amount is invalid: Invalid begin amount (auctionDetails.beginAmount > auctionDetails.endAmount)\n /// * Any failure in the 0x Match Orders\n /// @param buyOrder The Buyer's order. This order is for the current expected price of the auction.\n /// @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction).\n /// @param buySignature Proof that order was created by the buyer.\n /// @param sellSignature Proof that order was created by the seller.\n /// @return matchedFillResults amounts filled and fees paid by maker and taker of matched orders.\n function matchOrders(\n LibOrder.Order memory buyOrder,\n LibOrder.Order memory sellOrder,\n bytes memory buySignature,\n bytes memory sellSignature\n )\n public\n returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n AuctionDetails memory auctionDetails = getAuctionDetails(sellOrder);\n // Ensure the auction has not yet started\n require(\n auctionDetails.currentTimeSeconds >= auctionDetails.beginTimeSeconds,\n \"AUCTION_NOT_STARTED\"\n );\n // Ensure the auction has not expired. This will fail later in 0x but we can save gas by failing early\n require(\n sellOrder.expirationTimeSeconds > auctionDetails.currentTimeSeconds,\n \"AUCTION_EXPIRED\"\n );\n // Validate the buyer amount is greater than the current auction amount\n require(\n buyOrder.makerAssetAmount >= auctionDetails.currentAmount,\n \"INVALID_AMOUNT\"\n );\n // Match orders, maximally filling `buyOrder`\n matchedFillResults = EXCHANGE.matchOrders(\n buyOrder,\n sellOrder,\n buySignature,\n sellSignature\n );\n // The difference in sellOrder.takerAssetAmount and current amount is given as spread to the matcher\n // This may include additional spread from the buyOrder.makerAssetAmount and the currentAmount.\n // e.g currentAmount is 30, sellOrder.takerAssetAmount is 10 and buyOrder.makerAssetamount is 40.\n // 10 (40-30) is returned to the buyer, 20 (30-10) sent to the seller and 10 has previously\n // been transferred to the seller during matchOrders\n uint256 leftMakerAssetSpreadAmount = matchedFillResults.leftMakerAssetSpreadAmount;\n if (leftMakerAssetSpreadAmount > 0) {\n // ERC20 Asset data itself is encoded as follows:\n //\n // | Area | Offset | Length | Contents |\n // |----------|--------|---------|-------------------------------------|\n // | Header | 0 | 4 | function selector |\n // | Params | | 1 * 32 | function parameters: |\n // | | 4 | 12 | 1. token address padding |\n // | | 16 | 20 | 2. token address |\n bytes memory assetData = sellOrder.takerAssetData;\n address token = assetData.readAddress(16);\n // Calculate the excess from the buy order. This can occur if the buyer sends in a higher\n // amount than the calculated current amount\n uint256 buyerExcessAmount = safeSub(buyOrder.makerAssetAmount, auctionDetails.currentAmount);\n uint256 sellerExcessAmount = safeSub(leftMakerAssetSpreadAmount, buyerExcessAmount);\n // Return the difference between auctionDetails.currentAmount and sellOrder.takerAssetAmount\n // to the seller\n if (sellerExcessAmount > 0) {\n IERC20Token(token).transfer(sellOrder.makerAddress, sellerExcessAmount);\n }\n // Return the difference between buyOrder.makerAssetAmount and auctionDetails.currentAmount\n // to the buyer\n if (buyerExcessAmount > 0) {\n IERC20Token(token).transfer(buyOrder.makerAddress, buyerExcessAmount);\n }\n }\n return matchedFillResults;\n }\n\n /// @dev Calculates the Auction Details for the given order\n /// @param order The sell order\n /// @return AuctionDetails\n function getAuctionDetails(\n LibOrder.Order memory order\n )\n public\n returns (AuctionDetails memory auctionDetails)\n {\n uint256 makerAssetDataLength = order.makerAssetData.length;\n // It is unknown the encoded data of makerAssetData, we assume the last 64 bytes\n // are the Auction Details encoding.\n // Auction Details is encoded as follows:\n //\n // | Area | Offset | Length | Contents |\n // |----------|--------|---------|-------------------------------------|\n // | Params | | 2 * 32 | parameters: |\n // | | -64 | 32 | 1. auction begin unix timestamp |\n // | | -32 | 32 | 2. auction begin begin amount |\n // ERC20 asset data length is 4+32, 64 for auction details results in min length 100\n require(\n makerAssetDataLength >= 100,\n \"INVALID_ASSET_DATA\"\n );\n uint256 auctionBeginTimeSeconds = order.makerAssetData.readUint256(makerAssetDataLength - 64);\n uint256 auctionBeginAmount = order.makerAssetData.readUint256(makerAssetDataLength - 32);\n // Ensure the auction has a valid begin time\n require(\n order.expirationTimeSeconds > auctionBeginTimeSeconds,\n \"INVALID_BEGIN_TIME\"\n );\n uint256 auctionDurationSeconds = order.expirationTimeSeconds-auctionBeginTimeSeconds;\n // Ensure the auction goes from high to low\n uint256 minAmount = order.takerAssetAmount;\n require(\n auctionBeginAmount > minAmount,\n \"INVALID_AMOUNT\"\n );\n uint256 amountDelta = auctionBeginAmount-minAmount;\n // solhint-disable-next-line not-rely-on-time\n uint256 timestamp = block.timestamp;\n auctionDetails.beginTimeSeconds = auctionBeginTimeSeconds;\n auctionDetails.endTimeSeconds = order.expirationTimeSeconds;\n auctionDetails.beginAmount = auctionBeginAmount;\n auctionDetails.endAmount = minAmount;\n auctionDetails.currentTimeSeconds = timestamp;\n\n uint256 remainingDurationSeconds = order.expirationTimeSeconds-timestamp;\n if (timestamp < auctionBeginTimeSeconds) {\n // If the auction has not yet begun the current amount is the auctionBeginAmount\n auctionDetails.currentAmount = auctionBeginAmount;\n } else if (timestamp >= order.expirationTimeSeconds) {\n // If the auction has ended the current amount is the minAmount.\n // Auction end time is guaranteed by 0x Exchange due to the order expiration\n auctionDetails.currentAmount = minAmount;\n } else {\n auctionDetails.currentAmount = safeAdd(\n minAmount,\n safeDiv(\n safeMul(remainingDurationSeconds, amountDelta),\n auctionDurationSeconds\n )\n );\n }\n return auctionDetails;\n }\n}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IExchangeCore.sol\";\nimport \"./IMatchOrders.sol\";\nimport \"./ISignatureValidator.sol\";\nimport \"./ITransactions.sol\";\nimport \"./IAssetProxyDispatcher.sol\";\nimport \"./IWrapperFunctions.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract IExchange is\n IExchangeCore,\n IMatchOrders,\n ISignatureValidator,\n ITransactions,\n IAssetProxyDispatcher,\n IWrapperFunctions\n{}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchangeCore.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibFillResults.sol\";\n\n\ncontract IExchangeCore {\n\n /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch\n /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).\n /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.\n function cancelOrdersUpTo(uint256 targetOrderEpoch)\n external;\n\n /// @dev Fills the input order.\n /// @param order Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signature Proof that order has been created by maker.\n /// @return Amounts filled and fees paid by maker and taker.\n function fillOrder(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev After calling, the order can not be filled anymore.\n /// @param order Order struct containing order specifications.\n function cancelOrder(LibOrder.Order memory order)\n public;\n\n /// @dev Gets information about an order: status, hash, and amount filled.\n /// @param order Order to gather information on.\n /// @return OrderInfo Information about the order and its state.\n /// See LibOrder.OrderInfo for a complete description.\n function getOrderInfo(LibOrder.Order memory order)\n public\n view\n returns (LibOrder.OrderInfo memory orderInfo);\n}\n", + "@0x/contracts-libs/contracts/libs/LibOrder.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\nimport \"./LibEIP712.sol\";\n\n\ncontract LibOrder is\n LibEIP712\n{\n // Hash for the EIP712 Order Schema\n bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"Order(\",\n \"address makerAddress,\",\n \"address takerAddress,\",\n \"address feeRecipientAddress,\",\n \"address senderAddress,\",\n \"uint256 makerAssetAmount,\",\n \"uint256 takerAssetAmount,\",\n \"uint256 makerFee,\",\n \"uint256 takerFee,\",\n \"uint256 expirationTimeSeconds,\",\n \"uint256 salt,\",\n \"bytes makerAssetData,\",\n \"bytes takerAssetData\",\n \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state is unaffected by external factors, like account balances.\n enum OrderStatus {\n INVALID, // Default value\n INVALID_MAKER_ASSET_AMOUNT, // Order does not have a valid maker asset amount\n INVALID_TAKER_ASSET_AMOUNT, // Order does not have a valid taker asset amount\n FILLABLE, // Order is fillable\n EXPIRED, // Order has already expired\n FULLY_FILLED, // Order is fully filled\n CANCELLED // Order has been cancelled\n }\n\n // solhint-disable max-line-length\n struct Order {\n address makerAddress; // Address that created the order. \n address takerAddress; // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order. \n address feeRecipientAddress; // Address that will recieve fees when order is filled. \n address senderAddress; // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.\n uint256 makerAssetAmount; // Amount of makerAsset being offered by maker. Must be greater than 0. \n uint256 takerAssetAmount; // Amount of takerAsset being bid on by maker. Must be greater than 0. \n uint256 makerFee; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\n uint256 expirationTimeSeconds; // Timestamp in seconds at which order expires. \n uint256 salt; // Arbitrary number to facilitate uniqueness of the order's hash. \n bytes makerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n // solhint-enable max-line-length\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n\n // Assembly for more efficiently computing:\n // keccak256(abi.encodePacked(\n // EIP712_ORDER_SCHEMA_HASH,\n // bytes32(order.makerAddress),\n // bytes32(order.takerAddress),\n // bytes32(order.feeRecipientAddress),\n // bytes32(order.senderAddress),\n // order.makerAssetAmount,\n // order.takerAssetAmount,\n // order.makerFee,\n // order.takerFee,\n // order.expirationTimeSeconds,\n // order.salt,\n // keccak256(order.makerAssetData),\n // keccak256(order.takerAssetData)\n // ));\n\n assembly {\n // Calculate memory addresses that will be swapped out before hashing\n let pos1 := sub(order, 32)\n let pos2 := add(order, 320)\n let pos3 := add(order, 352)\n\n // Backup\n let temp1 := mload(pos1)\n let temp2 := mload(pos2)\n let temp3 := mload(pos3)\n \n // Hash in place\n mstore(pos1, schemaHash)\n mstore(pos2, makerAssetDataHash)\n mstore(pos3, takerAssetDataHash)\n result := keccak256(pos1, 416)\n \n // Restore\n mstore(pos1, temp1)\n mstore(pos2, temp2)\n mstore(pos3, temp3)\n }\n return result;\n }\n}\n", + "@0x/contracts-libs/contracts/libs/LibEIP712.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract LibEIP712 {\n\n // EIP191 header for EIP712 prefix\n string constant internal EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant internal EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant internal EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encodePacked(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n bytes32(address(this))\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32 result)\n {\n bytes32 eip712DomainHash = EIP712_DOMAIN_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct \n // ));\n\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}\n", + "@0x/contracts-libs/contracts/libs/LibFillResults.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\nimport \"@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol\";\n\n\ncontract LibFillResults is\n SafeMath\n{\n struct FillResults {\n uint256 makerAssetFilledAmount; // Total amount of makerAsset(s) filled.\n uint256 takerAssetFilledAmount; // Total amount of takerAsset(s) filled.\n uint256 makerFeePaid; // Total amount of ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\n }\n\n struct MatchedFillResults {\n FillResults left; // Amounts filled and fees paid of left order.\n FillResults right; // Amounts filled and fees paid of right order.\n uint256 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", + "@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol": "pragma solidity 0.4.24;\n\n\ncontract SafeMath {\n\n function safeMul(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n if (a == 0) {\n return 0;\n }\n uint256 c = a * b;\n require(\n c / a == b,\n \"UINT256_OVERFLOW\"\n );\n return c;\n }\n\n function safeDiv(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n uint256 c = a / b;\n return c;\n }\n\n function safeSub(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n require(\n b <= a,\n \"UINT256_UNDERFLOW\"\n );\n return a - b;\n }\n\n function safeAdd(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n uint256 c = a + b;\n require(\n c >= a,\n \"UINT256_OVERFLOW\"\n );\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\n }\n\n function max256(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min256(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\n }\n}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/IMatchOrders.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibFillResults.sol\";\n\n\ncontract IMatchOrders {\n\n /// @dev Match two complementary orders that have a profitable spread.\n /// Each order is filled at their respective price point. However, the calculations are\n /// carried out as though the orders are both being filled at the right order's price point.\n /// The profit made by the left order goes to the taker (who matched the two orders).\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n /// @param leftSignature Proof that order was created by the left maker.\n /// @param rightSignature Proof that order was created by the right maker.\n /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.\n function matchOrders(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder,\n bytes memory leftSignature,\n bytes memory rightSignature\n )\n public\n returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/ISignatureValidator.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\n \n /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.\n /// @param validatorAddress Address of Validator contract.\n /// @param approval Approval or disapproval of Validator contract.\n function setSignatureValidatorApproval(\n address validatorAddress,\n bool approval\n )\n external;\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/ITransactions.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\npragma solidity 0.4.24;\n\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract IAssetProxyDispatcher {\n\n /// @dev Registers an asset proxy to its asset proxy id.\n /// Once an asset proxy is registered, it cannot be unregistered.\n /// @param assetProxy Address of new asset proxy to register.\n function registerAssetProxy(address assetProxy)\n external;\n\n /// @dev Gets an asset proxy.\n /// @param assetProxyId Id of the asset proxy.\n /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.\n function getAssetProxy(bytes4 assetProxyId)\n external\n view\n returns (address);\n}\n", + "@0x/contracts-interfaces/contracts/protocol/Exchange/IWrapperFunctions.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibFillResults.sol\";\n\n\ncontract IWrapperFunctions {\n\n /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.\n /// @param order LibOrder.Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signature Proof that order has been created by maker.\n function fillOrKillOrder(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\n /// @param order LibOrder.Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signature Proof that order has been created by maker.\n /// @return Amounts filled and fees paid by maker and taker.\n function fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function batchFillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function batchFillOrKillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function batchFillOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been signed by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\n /// @param orders Array of order specifications.\n /// @param makerAssetFillAmount Desired amount of makerAsset to buy.\n /// @param signatures Proofs that orders have been signed by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\n /// @param orders Array of order specifications.\n /// @param makerAssetFillAmount Desired amount of makerAsset to buy.\n /// @param signatures Proofs that orders have been signed by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketBuyOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public;\n\n /// @dev Fetches information for all passed in orders\n /// @param orders Array of order specifications.\n /// @return Array of OrderInfo instances that correspond to each order.\n function getOrdersInfo(LibOrder.Order[] memory orders)\n public\n view\n returns (LibOrder.OrderInfo[] memory);\n}\n", + "@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract IERC20Token {\n\n // solhint-disable no-simple-event-func-name\n event Transfer(\n address indexed _from,\n address indexed _to,\n uint256 _value\n );\n\n event Approval(\n address indexed _owner,\n address indexed _spender,\n uint256 _value\n );\n\n /// @dev send `value` token to `to` from `msg.sender`\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return True if transfer was successful\n function transfer(address _to, uint256 _value)\n external\n returns (bool);\n\n /// @dev send `value` token to `to` from `from` on the condition it is approved by `from`\n /// @param _from The address of the sender\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return True if transfer was successful\n function transferFrom(\n address _from,\n address _to,\n uint256 _value\n )\n external\n returns (bool);\n \n /// @dev `msg.sender` approves `_spender` to spend `_value` tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @param _value The amount of wei to be approved for transfer\n /// @return Always true if the call has enough gas to complete execution\n function approve(address _spender, uint256 _value)\n external\n returns (bool);\n\n /// @dev Query total supply of token\n /// @return Total supply of token\n function totalSupply()\n external\n view\n returns (uint256);\n \n /// @param _owner The address from which the balance will be retrieved\n /// @return Balance of owner\n function balanceOf(address _owner)\n external\n view\n returns (uint256);\n\n /// @param _owner The address of the account owning tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @return Amount of remaining tokens allowed to spent\n function allowance(address _owner, address _spender)\n external\n view\n returns (uint256);\n}\n", + "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\nlibrary LibBytes {\n\n using LibBytes for bytes;\n\n /// @dev Gets the memory address for a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of byte array. This\n /// points to the header of the byte array which contains\n /// the length.\n function rawAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := input\n }\n return memoryAddress;\n }\n \n /// @dev Gets the memory address for the contents of a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of the contents of the byte array.\n function contentAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := add(input, 32)\n }\n return memoryAddress;\n }\n\n /// @dev Copies `length` bytes from memory location `source` to `dest`.\n /// @param dest memory address to copy bytes to.\n /// @param source memory address to copy bytes from.\n /// @param length number of bytes to copy.\n function memCopy(\n uint256 dest,\n uint256 source,\n uint256 length\n )\n internal\n pure\n {\n if (length < 32) {\n // Handle a partial word by reading destination and masking\n // off the bits we are interested in.\n // This correctly handles overlap, zero lengths and source == dest\n assembly {\n let mask := sub(exp(256, sub(32, length)), 1)\n let s := and(mload(source), not(mask))\n let d := and(mload(dest), mask)\n mstore(dest, or(s, d))\n }\n } else {\n // Skip the O(length) loop when source == dest.\n if (source == dest) {\n return;\n }\n\n // For large copies we copy whole words at a time. The final\n // word is aligned to the end of the range (instead of after the\n // previous) to handle partial words. So a copy will look like this:\n //\n // ####\n // ####\n // ####\n // ####\n //\n // We handle overlap in the source and destination range by\n // changing the copying direction. This prevents us from\n // overwriting parts of source that we still need to copy.\n //\n // This correctly handles source == dest\n //\n if (source > dest) {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because it\n // is easier to compare with in the loop, and these\n // are also the addresses we need for copying the\n // last bytes.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the last 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the last bytes in\n // source already due to overlap.\n let last := mload(sEnd)\n\n // Copy whole words front to back\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} lt(source, sEnd) {} {\n mstore(dest, mload(source))\n source := add(source, 32)\n dest := add(dest, 32)\n }\n \n // Write the last 32 bytes\n mstore(dEnd, last)\n }\n } else {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because those\n // are the starting points when copying a word at the end.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the first 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the first bytes in\n // source already due to overlap.\n let first := mload(source)\n\n // Copy whole words back to front\n // We use a signed comparisson here to allow dEnd to become\n // negative (happens when source and dest < 32). Valid\n // addresses in local memory will never be larger than\n // 2**255, so they can be safely re-interpreted as signed.\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} slt(dest, dEnd) {} {\n mstore(dEnd, mload(sEnd))\n sEnd := sub(sEnd, 32)\n dEnd := sub(dEnd, 32)\n }\n \n // Write the first 32 bytes\n mstore(dest, first)\n }\n }\n }\n }\n\n /// @dev Returns a slices from a byte array.\n /// @param b The byte array to take a slice from.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n function slice(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\n );\n \n // Create a new bytes structure and copy contents\n result = new bytes(to - from);\n memCopy(\n result.contentAddress(),\n b.contentAddress() + from,\n result.length\n );\n return result;\n }\n \n /// @dev Returns a slice from a byte array without preserving the input.\n /// @param b The byte array to take a slice from. Will be destroyed in the process.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.\n function sliceDestructive(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\n );\n \n // Create a new bytes structure around [from, to) in-place.\n assembly {\n result := add(b, from)\n mstore(result, sub(to, from))\n }\n return result;\n }\n\n /// @dev Pops the last byte off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The byte that was popped off.\n function popLastByte(bytes memory b)\n internal\n pure\n returns (bytes1 result)\n {\n require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\n );\n\n // Store last byte.\n result = b[b.length - 1];\n\n assembly {\n // Decrement length of byte array.\n let newLen := sub(mload(b), 1)\n mstore(b, newLen)\n }\n return result;\n }\n\n /// @dev Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\n mstore(b, newLen)\n }\n return result;\n }\n\n /// @dev Tests equality of two byte arrays.\n /// @param lhs First byte array to compare.\n /// @param rhs Second byte array to compare.\n /// @return True if arrays are the same. False otherwise.\n function equals(\n bytes memory lhs,\n bytes memory rhs\n )\n internal\n pure\n returns (bool equal)\n {\n // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.\n // We early exit on unequal lengths, but keccak would also correctly\n // handle this.\n return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);\n }\n\n /// @dev Reads an address from a position in a byte array.\n /// @param b Byte array containing an address.\n /// @param index Index in byte array of address.\n /// @return address from byte array.\n function readAddress(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Read address from array memory\n assembly {\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 20-byte mask to obtain address\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\n }\n return result;\n }\n\n /// @dev Writes an address into a specific position in a byte array.\n /// @param b Byte array to insert address into.\n /// @param index Index in byte array of address.\n /// @param input Address to put into byte array.\n function writeAddress(\n bytes memory b,\n uint256 index,\n address input\n )\n internal\n pure\n {\n require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Store address into array memory\n assembly {\n // The address occupies 20 bytes and mstore stores 32 bytes.\n // First fetch the 32-byte word where we'll be storing the address, then\n // apply a mask so we have only the bytes in the word that the address will not occupy.\n // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.\n\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address\n let neighbors := and(\n mload(add(b, index)),\n 0xffffffffffffffffffffffff0000000000000000000000000000000000000000\n )\n \n // Make sure input address is clean.\n // (Solidity does not guarantee this)\n input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)\n\n // Store the neighbors and address into memory\n mstore(add(b, index), xor(input, neighbors))\n }\n }\n\n /// @dev Reads a bytes32 value from a position in a byte array.\n /// @param b Byte array containing a bytes32 value.\n /// @param index Index in byte array of bytes32 value.\n /// @return bytes32 value from byte array.\n function readBytes32(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes32 result)\n {\n require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\n );\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n result := mload(add(b, index))\n }\n return result;\n }\n\n /// @dev Writes a bytes32 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input bytes32 to put into byte array.\n function writeBytes32(\n bytes memory b,\n uint256 index,\n bytes32 input\n )\n internal\n pure\n {\n require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\n );\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n mstore(add(b, index), input)\n }\n }\n\n /// @dev Reads a uint256 value from a position in a byte array.\n /// @param b Byte array containing a uint256 value.\n /// @param index Index in byte array of uint256 value.\n /// @return uint256 value from byte array.\n function readUint256(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (uint256 result)\n {\n result = uint256(readBytes32(b, index));\n return result;\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input uint256 to put into byte array.\n function writeUint256(\n bytes memory b,\n uint256 index,\n uint256 input\n )\n internal\n pure\n {\n writeBytes32(b, index, bytes32(input));\n }\n\n /// @dev Reads an unpadded bytes4 value from a position in a byte array.\n /// @param b Byte array containing a bytes4 value.\n /// @param index Index in byte array of bytes4 value.\n /// @return bytes4 value from byte array.\n function readBytes4(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n\n // Arrays are prefixed by a 32 byte length field\n index += 32;\n\n // Read the bytes4 from array memory\n assembly {\n result := mload(add(b, index))\n // Solidity does not require us to clean the trailing bytes.\n // We do it anyway\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\n }\n return result;\n }\n\n /// @dev Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of is valid, given\n // length of input\n require(\n b.length >= index + 32 + input.length, // 32 bytes to store length\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy into \n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of \n input.length + 32 // +32 bytes to store length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n" + }, + "sourceTreeHashHex": "0x4be45134ccdebcf000c4e09f6aed69041411babf993cfba6871e9ad73369122f", + "compiler": { + "name": "solc", + "version": "soljson-v0.4.24+commit.e67f0147.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + } + } + }, + "networks": {} +} \ No newline at end of file diff --git a/packages/contract-artifacts/src/index.ts b/packages/contract-artifacts/src/index.ts index f30276dd9..bd5f8fee3 100644 --- a/packages/contract-artifacts/src/index.ts +++ b/packages/contract-artifacts/src/index.ts @@ -1,4 +1,5 @@ import * as AssetProxyOwner from '../artifacts/AssetProxyOwner.json'; +import * as DutchAuction from '../artifacts/DutchAuction.json'; import * as DummyERC20Token from '../artifacts/DummyERC20Token.json'; import * as DummyERC721Token from '../artifacts/DummyERC721Token.json'; import * as ERC20Proxy from '../artifacts/ERC20Proxy.json'; @@ -15,6 +16,7 @@ import * as ZRXToken from '../artifacts/ZRXToken.json'; export { AssetProxyOwner, + DutchAuction, DummyERC20Token, DummyERC721Token, ERC20Proxy, diff --git a/packages/contract-artifacts/tsconfig.json b/packages/contract-artifacts/tsconfig.json index cce086209..59169fceb 100644 --- a/packages/contract-artifacts/tsconfig.json +++ b/packages/contract-artifacts/tsconfig.json @@ -8,6 +8,7 @@ "include": ["./src/**/*"], "files": [ "./artifacts/AssetProxyOwner.json", + "./artifacts/DutchAuction.json", "./artifacts/DummyERC20Token.json", "./artifacts/DummyERC721Token.json", "./artifacts/ERC20Proxy.json", diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index 0c535bd5c..396505866 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -20,6 +20,7 @@ import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper'; import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper'; import { ForwarderWrapper } from './contract_wrappers/forwarder_wrapper'; import { OrderValidatorWrapper } from './contract_wrappers/order_validator_wrapper'; +import { DutchAuctionWrapper } from './contract_wrappers/dutch_auction_wrapper'; import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema'; import { ContractWrappersConfig } from './types'; import { assert } from './utils/assert'; @@ -65,6 +66,10 @@ export class ContractWrappers { * An instance of the OrderValidatorWrapper class containing methods for interacting with any OrderValidator smart contract. */ public orderValidator: OrderValidatorWrapper; + /** + * An instance of the DutchAuctionWrapper class containing methods for interacting with any DutchAuction smart contract. + */ + public dutchAuction: DutchAuctionWrapper; private readonly _web3Wrapper: Web3Wrapper; /** @@ -141,6 +146,11 @@ export class ContractWrappers { config.networkId, contractAddresses.orderValidator, ); + this.dutchAuction = new DutchAuctionWrapper( + this._web3Wrapper, + config.networkId, + contractAddresses.orderValidator, + ); } /** * Unsubscribes from all subscriptions for all contracts. diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts new file mode 100644 index 000000000..500e7a63d --- /dev/null +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -0,0 +1,151 @@ +import { artifacts as protocolArtifacts } from '@0x/contracts-protocol'; +import { DutchAuctionContract } from '@0x/abi-gen-wrappers'; +import { DutchAuction } from '@0x/contract-artifacts'; +import { LogDecoder } from '@0x/contracts-test-utils'; +import { artifacts as tokensArtifacts } from '@0x/contracts-tokens'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; +import { DutchAuctionDetails, SignedOrder } from '@0x/types'; +import { ContractAbi } from 'ethereum-types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { BigNumber } from '@0x/utils'; +import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; +import * as _ from 'lodash'; +import ethAbi = require('ethereumjs-abi'); +import { schemas } from '@0x/json-schemas'; +import { assert } from '../utils/assert'; +import ethUtil = require('ethereumjs-util'); + +import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; +import { txOptsSchema } from '../schemas/tx_opts_schema'; +import { OrderTransactionOpts } from '../types'; +import { ContractWrapper } from './contract_wrapper'; +import { ExchangeWrapperError } from '../types'; + +export class DutchAuctionWrapper extends ContractWrapper { + public abi: ContractAbi = DutchAuction.compilerOutput.abi; + public address: string; + private _dutchAuctionContractIfExists?: DutchAuctionContract; + /** + * Instantiate DutchAuctionWrapper + * @param web3Wrapper Web3Wrapper instance to use. + * @param networkId Desired networkId. + * @param address The address of the Dutch Auction contract. If undefined, will + * default to the known address corresponding to the networkId. + */ + constructor( + web3Wrapper: Web3Wrapper, + networkId: number, + address: string, + ) { + super(web3Wrapper, networkId); + this.address = address; + } + /** + * Matches the buy and sell orders at an amount given the following: the current block time, the auction + * start time and the auction begin amount. The sell order is a an order at the lowest amount + * at the end of the auction. Excess from the match is transferred to the seller. + * Over time the price moves from beginAmount to endAmount given the current block.timestamp. + * @param buyOrder The Buyer's order. This order is for the current expected price of the auction. + * @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction). + * @param from Address the transaction is being sent from. + * @return Transaction receipt with decoded logs. + */ + public async matchOrdersAsync( + buyOrder: SignedOrder, + sellOrder: SignedOrder, + takerAddress: string, + orderTransactionOpts: OrderTransactionOpts = { shouldValidate: true }, + ): Promise { + // type assertions + assert.doesConformToSchema('buyOrder', buyOrder, schemas.signedOrderSchema); + assert.doesConformToSchema('sellOrder', sellOrder, schemas.signedOrderSchema); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); + const normalizedTakerAddress = takerAddress.toLowerCase(); + // other assertions + if ( + sellOrder.makerAssetData !== buyOrder.takerAssetData || + sellOrder.takerAssetData !== buyOrder.makerAssetData + ) { + throw new Error(ExchangeWrapperError.AssetDataMismatch); + } + // get contract + const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); + // validate transaction + if (orderTransactionOpts.shouldValidate) { + await dutchAuctionInstance.matchOrders.callAsync( + buyOrder, + sellOrder, + buyOrder.signature, + sellOrder.signature, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + nonce: orderTransactionOpts.nonce, + }, + ); + } + // send transaction + const txHash = await dutchAuctionInstance.matchOrders.sendTransactionAsync( + buyOrder, + sellOrder, + buyOrder.signature, + sellOrder.signature, + { + from: normalizedTakerAddress, + gas: orderTransactionOpts.gasLimit, + gasPrice: orderTransactionOpts.gasPrice, + nonce: orderTransactionOpts.nonce, + }, + ); + return txHash; + } + /** + * Calculates the Auction Details for the given order + * @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction). + * @return The dutch auction details. + */ + public async getAuctionDetailsAsync(sellOrder: SignedOrder): Promise { + // type assertions + assert.doesConformToSchema('sellOrder', sellOrder, schemas.signedOrderSchema); + // get contract + const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); + // call contract + const afterAuctionDetails = await dutchAuctionInstance.getAuctionDetails.callAsync(sellOrder); + return afterAuctionDetails; + } + private async _getDutchAuctionContractAsync(): Promise { + if (!_.isUndefined(this._dutchAuctionContractIfExists)) { + return this._dutchAuctionContractIfExists; + } + const contractInstance = new DutchAuctionContract( + this.abi, + this.address, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + this._dutchAuctionContractIfExists = contractInstance; + return this._dutchAuctionContractIfExists; + } + /** + * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex + * encoded assetData string, containing information both about the asset being traded and the + * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. + * @param assetData Hex encoded assetData string for the asset being auctioned. + * @param beginTimeSeconds Begin time of the dutch auction. + * @param beginAmount Starting amount being sold in the dutch auction. + * @return The hex encoded assetData string. + */ + public static encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string { + const assetDataBuffer = ethUtil.toBuffer(assetData); + const abiEncodedAuctionData = (ethAbi as any).rawEncode( + ['uint256', 'uint256'], + [beginTimeSeconds.toString(), beginAmount.toString()], + ); + const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); + const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); + const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); + return dutchAuctionData; + }; +} diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index d66ff5c9c..5c64dbbc6 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -34,6 +34,7 @@ export { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper'; export { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper'; export { ForwarderWrapper } from './contract_wrappers/forwarder_wrapper'; export { OrderValidatorWrapper } from './contract_wrappers/order_validator_wrapper'; +export { DutchAuctionWrapper } from './contract_wrappers/dutch_auction_wrapper'; export { TransactionEncoder } from './utils/transaction_encoder'; diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts new file mode 100644 index 000000000..ad8b3bd31 --- /dev/null +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -0,0 +1,156 @@ +import { BlockchainLifecycle } from '@0x/dev-utils'; +import { FillScenarios } from '@0x/fill-scenarios'; +import { assetDataUtils } from '@0x/order-utils'; +import { SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import * as chai from 'chai'; +import 'mocha'; + +import { ContractWrappers, OrderStatus } from '../src'; + +import { chaiSetup } from './utils/chai_setup'; +import { constants } from './utils/constants'; +import { migrateOnceAsync } from './utils/migrate'; +import { tokenUtils } from './utils/token_utils'; +import { provider, web3Wrapper } from './utils/web3_wrapper'; +import { getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; +import { DutchAuction } from '@0x/contract-artifacts'; +import { DutchAuctionWrapper } from '../src/contract_wrappers/dutch_auction_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); + +// tslint:disable:custom-no-magic-numbers +describe.only('DutchAuctionWrapper', () => { + const fillableAmount = new BigNumber(5); + const tenMinutesInSeconds = 10 * 60; + let contractWrappers: ContractWrappers; + let fillScenarios: FillScenarios; + let exchangeContractAddress: string; + let zrxTokenAddress: string; + let userAddresses: string[]; + let makerAddress: string; + let takerAddress: string; + let makerTokenAddress: string; + let takerTokenAddress: string; + let makerAssetData: string; + let takerAssetData: string; + let buyOrder: SignedOrder; + let sellOrder: SignedOrder; + let makerTokenAssetData: string; + let takerTokenAssetData: string; + before(async () => { + console.log(`BEOGIN DEPLOYINH`); + const contractAddresses = await migrateOnceAsync(); + await blockchainLifecycle.startAsync(); + const config = { + networkId: constants.TESTRPC_NETWORK_ID, + contractAddresses, + blockPollingIntervalMs: 10, + }; + + contractWrappers = new ContractWrappers(provider, config); + console.log(`DEPLOYINH`); + exchangeContractAddress = contractWrappers.exchange.address; + userAddresses = await web3Wrapper.getAvailableAddressesAsync(); + zrxTokenAddress = contractWrappers.exchange.zrxTokenAddress; + fillScenarios = new FillScenarios( + provider, + userAddresses, + zrxTokenAddress, + exchangeContractAddress, + contractWrappers.erc20Proxy.address, + contractWrappers.erc721Proxy.address, + ); + [, makerAddress, takerAddress] = userAddresses; + [makerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); + takerTokenAddress = contractWrappers.forwarder.etherTokenAddress; + // construct asset data for tokens being swapped + [makerTokenAssetData, takerTokenAssetData] = [ + assetDataUtils.encodeERC20AssetData(makerTokenAddress), + assetDataUtils.encodeERC20AssetData(takerTokenAddress), + ]; + // encode auction details in maker asset data + const auctionBeginAmount = fillableAmount; + const currentBlockTimestamp = await getLatestBlockTimestampAsync(); + const auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); + makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( + makerTokenAssetData, + auctionBeginTimeSeconds, + auctionBeginAmount + ); + takerAssetData = takerTokenAssetData; + // create sell / buy orders for auction + // note that the maker/taker asset datas are swapped in the `buyOrder` + sellOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + constants.NULL_ADDRESS, + fillableAmount, + ); + buyOrder = await fillScenarios.createFillableSignedOrderAsync( + takerAssetData, + makerAssetData, + makerAddress, + constants.NULL_ADDRESS, + fillableAmount, + ); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + describe('#matchOrdersAsync', () => { + it('should match two orders', async () => { + const txHash = await contractWrappers.dutchAuction.matchOrdersAsync(buyOrder, sellOrder, takerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + }); + it('should throw when invalid transaction and shouldValidate is true', async () => { + // request match with bad buy/sell orders + const badSellOrder = buyOrder; + const badBuyOrder = sellOrder; + return expect( + await contractWrappers.dutchAuction.matchOrdersAsync( + badBuyOrder, + badSellOrder, + takerAddress, + { + shouldValidate: true, + }, + ), + ).to.be.rejectedWith('COMPLETE_FILL_FAILED'); + }); + }); + + describe('#getAuctionDetailsAsync', () => { + it('should be worth the begin price at the begining of the auction', async () => { + // setup auction details + const auctionBeginAmount = fillableAmount; + const currentBlockTimestamp = await getLatestBlockTimestampAsync(); + const auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); + const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( + makerTokenAssetData, + auctionBeginTimeSeconds, + auctionBeginAmount + ); + const order = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + constants.NULL_ADDRESS, + fillableAmount, + ); + const auctionDetails = await contractWrappers.dutchAuction.getAuctionDetailsAsync(order); + expect(auctionDetails.currentTimeSeconds).to.be.bignumber.lte(auctionBeginTimeSeconds); + expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionBeginAmount); + expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount); + }); + }); +}); diff --git a/packages/migrations/src/migration.ts b/packages/migrations/src/migration.ts index c684c4970..99d1719f1 100644 --- a/packages/migrations/src/migration.ts +++ b/packages/migrations/src/migration.ts @@ -141,6 +141,14 @@ export async function runMigrationsAsync(provider: Provider, txDefaults: Partial zrxAssetData, ); + // DutchAuction + const dutchAuction = await wrappers.DutchAuctionContract.deployFrom0xArtifactAsync( + artifacts.DutchAuction, + provider, + txDefaults, + exchange.address, + ); + // Fund the Forwarder with ZRX const zrxDecimals = await zrxToken.decimals.callAsync(); const zrxForwarderAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5000), zrxDecimals); @@ -157,6 +165,7 @@ export async function runMigrationsAsync(provider: Provider, txDefaults: Partial assetProxyOwner: assetProxyOwner.address, forwarder: forwarder.address, orderValidator: orderValidator.address, + dutchAuction: dutchAuction.address, }; } diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts index 0fc166969..f314891e2 100644 --- a/packages/order-utils/src/asset_data_utils.ts +++ b/packages/order-utils/src/asset_data_utils.ts @@ -305,24 +305,4 @@ export const assetDataUtils = { throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`); } }, - /** - * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex - * encoded assetData string, containing information both about the asset being traded and the - * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. - * @param assetData Hex encoded assetData string for the asset being auctioned. - * @param beginTimeSeconds Begin time of the dutch auction. - * @param beginAmount Starting amount being sold in the dutch auction. - * @return The hex encoded assetData string. - */ - encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string { - const assetDataBuffer = ethUtil.toBuffer(assetData); - const abiEncodedAuctionData = (ethAbi as any).rawEncode( - ['uint256', 'uint256'], - [beginTimeSeconds.toString(), beginAmount.toString()], - ); - const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); - const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); - const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); - return dutchAuctionData; - }, }; -- cgit From 09afee55ed4afc9ff41ecaf7417e4c8761bb8f87 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 20 Dec 2018 16:57:47 -0800 Subject: Removed unnecessary fields from dutch auction artifacts --- .../contract-artifacts/artifacts/DutchAuction.json | 86 +--------------------- 1 file changed, 2 insertions(+), 84 deletions(-) (limited to 'packages') diff --git a/packages/contract-artifacts/artifacts/DutchAuction.json b/packages/contract-artifacts/artifacts/DutchAuction.json index 2c1998034..3c1cb8c4c 100644 --- a/packages/contract-artifacts/artifacts/DutchAuction.json +++ b/packages/contract-artifacts/artifacts/DutchAuction.json @@ -306,87 +306,5 @@ } } }, - "sources": { - "DutchAuction/DutchAuction.sol": { - "id": 28 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol": { - "id": 1 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchangeCore.sol": { - "id": 2 - }, - "@0x/contracts-libs/contracts/libs/LibOrder.sol": { - "id": 13 - }, - "@0x/contracts-libs/contracts/libs/LibEIP712.sol": { - "id": 9 - }, - "@0x/contracts-libs/contracts/libs/LibFillResults.sol": { - "id": 11 - }, - "@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol": { - "id": 20 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/IMatchOrders.sol": { - "id": 3 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/ISignatureValidator.sol": { - "id": 4 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/ITransactions.sol": { - "id": 5 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/IAssetProxyDispatcher.sol": { - "id": 0 - }, - "@0x/contracts-interfaces/contracts/protocol/Exchange/IWrapperFunctions.sol": { - "id": 6 - }, - "@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol": { - "id": 14 - }, - "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol": { - "id": 17 - } - }, - "sourceCodes": { - "DutchAuction/DutchAuction.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol\";\nimport \"@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol\";\nimport \"@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol\";\n\n\ncontract DutchAuction is\n SafeMath\n{\n using LibBytes for bytes;\n\n // solhint-disable var-name-mixedcase\n IExchange internal EXCHANGE;\n\n struct AuctionDetails {\n uint256 beginTimeSeconds; // Auction begin unix timestamp: sellOrder.makerAssetData\n uint256 endTimeSeconds; // Auction end unix timestamp: sellOrder.expiryTimeSeconds\n uint256 beginAmount; // Auction begin amount: sellOrder.makerAssetData\n uint256 endAmount; // Auction end amount: sellOrder.takerAssetAmount\n uint256 currentAmount; // Calculated amount given block.timestamp\n uint256 currentTimeSeconds; // block.timestamp\n }\n\n constructor (address _exchange)\n public\n {\n EXCHANGE = IExchange(_exchange);\n }\n\n /// @dev Matches the buy and sell orders at an amount given the following: the current block time, the auction\n /// start time and the auction begin amount. The sell order is a an order at the lowest amount\n /// at the end of the auction. Excess from the match is transferred to the seller.\n /// Over time the price moves from beginAmount to endAmount given the current block.timestamp.\n /// sellOrder.expiryTimeSeconds is the end time of the auction.\n /// sellOrder.takerAssetAmount is the end amount of the auction (lowest possible amount).\n /// sellOrder.makerAssetData is the ABI encoded Asset Proxy data with the following data appended\n /// buyOrder.makerAssetData is the buyers bid on the auction, must meet the amount for the current block timestamp\n /// (uint256 beginTimeSeconds, uint256 beginAmount).\n /// This function reverts in the following scenarios:\n /// * Auction has not started (auctionDetails.currentTimeSeconds < auctionDetails.beginTimeSeconds)\n /// * Auction has expired (auctionDetails.endTimeSeconds < auctionDetails.currentTimeSeconds)\n /// * Amount is invalid: Buy order amount is too low (buyOrder.makerAssetAmount < auctionDetails.currentAmount)\n /// * Amount is invalid: Invalid begin amount (auctionDetails.beginAmount > auctionDetails.endAmount)\n /// * Any failure in the 0x Match Orders\n /// @param buyOrder The Buyer's order. This order is for the current expected price of the auction.\n /// @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction).\n /// @param buySignature Proof that order was created by the buyer.\n /// @param sellSignature Proof that order was created by the seller.\n /// @return matchedFillResults amounts filled and fees paid by maker and taker of matched orders.\n function matchOrders(\n LibOrder.Order memory buyOrder,\n LibOrder.Order memory sellOrder,\n bytes memory buySignature,\n bytes memory sellSignature\n )\n public\n returns (LibFillResults.MatchedFillResults memory matchedFillResults)\n {\n AuctionDetails memory auctionDetails = getAuctionDetails(sellOrder);\n // Ensure the auction has not yet started\n require(\n auctionDetails.currentTimeSeconds >= auctionDetails.beginTimeSeconds,\n \"AUCTION_NOT_STARTED\"\n );\n // Ensure the auction has not expired. This will fail later in 0x but we can save gas by failing early\n require(\n sellOrder.expirationTimeSeconds > auctionDetails.currentTimeSeconds,\n \"AUCTION_EXPIRED\"\n );\n // Validate the buyer amount is greater than the current auction amount\n require(\n buyOrder.makerAssetAmount >= auctionDetails.currentAmount,\n \"INVALID_AMOUNT\"\n );\n // Match orders, maximally filling `buyOrder`\n matchedFillResults = EXCHANGE.matchOrders(\n buyOrder,\n sellOrder,\n buySignature,\n sellSignature\n );\n // The difference in sellOrder.takerAssetAmount and current amount is given as spread to the matcher\n // This may include additional spread from the buyOrder.makerAssetAmount and the currentAmount.\n // e.g currentAmount is 30, sellOrder.takerAssetAmount is 10 and buyOrder.makerAssetamount is 40.\n // 10 (40-30) is returned to the buyer, 20 (30-10) sent to the seller and 10 has previously\n // been transferred to the seller during matchOrders\n uint256 leftMakerAssetSpreadAmount = matchedFillResults.leftMakerAssetSpreadAmount;\n if (leftMakerAssetSpreadAmount > 0) {\n // ERC20 Asset data itself is encoded as follows:\n //\n // | Area | Offset | Length | Contents |\n // |----------|--------|---------|-------------------------------------|\n // | Header | 0 | 4 | function selector |\n // | Params | | 1 * 32 | function parameters: |\n // | | 4 | 12 | 1. token address padding |\n // | | 16 | 20 | 2. token address |\n bytes memory assetData = sellOrder.takerAssetData;\n address token = assetData.readAddress(16);\n // Calculate the excess from the buy order. This can occur if the buyer sends in a higher\n // amount than the calculated current amount\n uint256 buyerExcessAmount = safeSub(buyOrder.makerAssetAmount, auctionDetails.currentAmount);\n uint256 sellerExcessAmount = safeSub(leftMakerAssetSpreadAmount, buyerExcessAmount);\n // Return the difference between auctionDetails.currentAmount and sellOrder.takerAssetAmount\n // to the seller\n if (sellerExcessAmount > 0) {\n IERC20Token(token).transfer(sellOrder.makerAddress, sellerExcessAmount);\n }\n // Return the difference between buyOrder.makerAssetAmount and auctionDetails.currentAmount\n // to the buyer\n if (buyerExcessAmount > 0) {\n IERC20Token(token).transfer(buyOrder.makerAddress, buyerExcessAmount);\n }\n }\n return matchedFillResults;\n }\n\n /// @dev Calculates the Auction Details for the given order\n /// @param order The sell order\n /// @return AuctionDetails\n function getAuctionDetails(\n LibOrder.Order memory order\n )\n public\n returns (AuctionDetails memory auctionDetails)\n {\n uint256 makerAssetDataLength = order.makerAssetData.length;\n // It is unknown the encoded data of makerAssetData, we assume the last 64 bytes\n // are the Auction Details encoding.\n // Auction Details is encoded as follows:\n //\n // | Area | Offset | Length | Contents |\n // |----------|--------|---------|-------------------------------------|\n // | Params | | 2 * 32 | parameters: |\n // | | -64 | 32 | 1. auction begin unix timestamp |\n // | | -32 | 32 | 2. auction begin begin amount |\n // ERC20 asset data length is 4+32, 64 for auction details results in min length 100\n require(\n makerAssetDataLength >= 100,\n \"INVALID_ASSET_DATA\"\n );\n uint256 auctionBeginTimeSeconds = order.makerAssetData.readUint256(makerAssetDataLength - 64);\n uint256 auctionBeginAmount = order.makerAssetData.readUint256(makerAssetDataLength - 32);\n // Ensure the auction has a valid begin time\n require(\n order.expirationTimeSeconds > auctionBeginTimeSeconds,\n \"INVALID_BEGIN_TIME\"\n );\n uint256 auctionDurationSeconds = order.expirationTimeSeconds-auctionBeginTimeSeconds;\n // Ensure the auction goes from high to low\n uint256 minAmount = order.takerAssetAmount;\n require(\n auctionBeginAmount > minAmount,\n \"INVALID_AMOUNT\"\n );\n uint256 amountDelta = auctionBeginAmount-minAmount;\n // solhint-disable-next-line not-rely-on-time\n uint256 timestamp = block.timestamp;\n auctionDetails.beginTimeSeconds = auctionBeginTimeSeconds;\n auctionDetails.endTimeSeconds = order.expirationTimeSeconds;\n auctionDetails.beginAmount = auctionBeginAmount;\n auctionDetails.endAmount = minAmount;\n auctionDetails.currentTimeSeconds = timestamp;\n\n uint256 remainingDurationSeconds = order.expirationTimeSeconds-timestamp;\n if (timestamp < auctionBeginTimeSeconds) {\n // If the auction has not yet begun the current amount is the auctionBeginAmount\n auctionDetails.currentAmount = auctionBeginAmount;\n } else if (timestamp >= order.expirationTimeSeconds) {\n // If the auction has ended the current amount is the minAmount.\n // Auction end time is guaranteed by 0x Exchange due to the order expiration\n auctionDetails.currentAmount = minAmount;\n } else {\n auctionDetails.currentAmount = safeAdd(\n minAmount,\n safeDiv(\n safeMul(remainingDurationSeconds, amountDelta),\n auctionDurationSeconds\n )\n );\n }\n return auctionDetails;\n }\n}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"./IExchangeCore.sol\";\nimport \"./IMatchOrders.sol\";\nimport \"./ISignatureValidator.sol\";\nimport \"./ITransactions.sol\";\nimport \"./IAssetProxyDispatcher.sol\";\nimport \"./IWrapperFunctions.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract IExchange is\n IExchangeCore,\n IMatchOrders,\n ISignatureValidator,\n ITransactions,\n IAssetProxyDispatcher,\n IWrapperFunctions\n{}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchangeCore.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibFillResults.sol\";\n\n\ncontract IExchangeCore {\n\n /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch\n /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).\n /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.\n function cancelOrdersUpTo(uint256 targetOrderEpoch)\n external;\n\n /// @dev Fills the input order.\n /// @param order Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signature Proof that order has been created by maker.\n /// @return Amounts filled and fees paid by maker and taker.\n function fillOrder(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev After calling, the order can not be filled anymore.\n /// @param order Order struct containing order specifications.\n function cancelOrder(LibOrder.Order memory order)\n public;\n\n /// @dev Gets information about an order: status, hash, and amount filled.\n /// @param order Order to gather information on.\n /// @return OrderInfo Information about the order and its state.\n /// See LibOrder.OrderInfo for a complete description.\n function getOrderInfo(LibOrder.Order memory order)\n public\n view\n returns (LibOrder.OrderInfo memory orderInfo);\n}\n", - "@0x/contracts-libs/contracts/libs/LibOrder.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\nimport \"./LibEIP712.sol\";\n\n\ncontract LibOrder is\n LibEIP712\n{\n // Hash for the EIP712 Order Schema\n bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"Order(\",\n \"address makerAddress,\",\n \"address takerAddress,\",\n \"address feeRecipientAddress,\",\n \"address senderAddress,\",\n \"uint256 makerAssetAmount,\",\n \"uint256 takerAssetAmount,\",\n \"uint256 makerFee,\",\n \"uint256 takerFee,\",\n \"uint256 expirationTimeSeconds,\",\n \"uint256 salt,\",\n \"bytes makerAssetData,\",\n \"bytes takerAssetData\",\n \")\"\n ));\n\n // A valid order remains fillable until it is expired, fully filled, or cancelled.\n // An order's state is unaffected by external factors, like account balances.\n enum OrderStatus {\n INVALID, // Default value\n INVALID_MAKER_ASSET_AMOUNT, // Order does not have a valid maker asset amount\n INVALID_TAKER_ASSET_AMOUNT, // Order does not have a valid taker asset amount\n FILLABLE, // Order is fillable\n EXPIRED, // Order has already expired\n FULLY_FILLED, // Order is fully filled\n CANCELLED // Order has been cancelled\n }\n\n // solhint-disable max-line-length\n struct Order {\n address makerAddress; // Address that created the order. \n address takerAddress; // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order. \n address feeRecipientAddress; // Address that will recieve fees when order is filled. \n address senderAddress; // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.\n uint256 makerAssetAmount; // Amount of makerAsset being offered by maker. Must be greater than 0. \n uint256 takerAssetAmount; // Amount of takerAsset being bid on by maker. Must be greater than 0. \n uint256 makerFee; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.\n uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.\n uint256 expirationTimeSeconds; // Timestamp in seconds at which order expires. \n uint256 salt; // Arbitrary number to facilitate uniqueness of the order's hash. \n bytes makerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The last byte references the id of this proxy.\n bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.\n }\n // solhint-enable max-line-length\n\n struct OrderInfo {\n uint8 orderStatus; // Status that describes order's validity and fillability.\n bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash).\n uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.\n }\n\n /// @dev Calculates Keccak-256 hash of the order.\n /// @param order The order structure.\n /// @return Keccak-256 EIP712 hash of the order.\n function getOrderHash(Order memory order)\n internal\n view\n returns (bytes32 orderHash)\n {\n orderHash = hashEIP712Message(hashOrder(order));\n return orderHash;\n }\n\n /// @dev Calculates EIP712 hash of the order.\n /// @param order The order structure.\n /// @return EIP712 hash of the order.\n function hashOrder(Order memory order)\n internal\n pure\n returns (bytes32 result)\n {\n bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH;\n bytes32 makerAssetDataHash = keccak256(order.makerAssetData);\n bytes32 takerAssetDataHash = keccak256(order.takerAssetData);\n\n // Assembly for more efficiently computing:\n // keccak256(abi.encodePacked(\n // EIP712_ORDER_SCHEMA_HASH,\n // bytes32(order.makerAddress),\n // bytes32(order.takerAddress),\n // bytes32(order.feeRecipientAddress),\n // bytes32(order.senderAddress),\n // order.makerAssetAmount,\n // order.takerAssetAmount,\n // order.makerFee,\n // order.takerFee,\n // order.expirationTimeSeconds,\n // order.salt,\n // keccak256(order.makerAssetData),\n // keccak256(order.takerAssetData)\n // ));\n\n assembly {\n // Calculate memory addresses that will be swapped out before hashing\n let pos1 := sub(order, 32)\n let pos2 := add(order, 320)\n let pos3 := add(order, 352)\n\n // Backup\n let temp1 := mload(pos1)\n let temp2 := mload(pos2)\n let temp3 := mload(pos3)\n \n // Hash in place\n mstore(pos1, schemaHash)\n mstore(pos2, makerAssetDataHash)\n mstore(pos3, takerAssetDataHash)\n result := keccak256(pos1, 416)\n \n // Restore\n mstore(pos1, temp1)\n mstore(pos2, temp2)\n mstore(pos3, temp3)\n }\n return result;\n }\n}\n", - "@0x/contracts-libs/contracts/libs/LibEIP712.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract LibEIP712 {\n\n // EIP191 header for EIP712 prefix\n string constant internal EIP191_HEADER = \"\\x19\\x01\";\n\n // EIP712 Domain Name value\n string constant internal EIP712_DOMAIN_NAME = \"0x Protocol\";\n\n // EIP712 Domain Version value\n string constant internal EIP712_DOMAIN_VERSION = \"2\";\n\n // Hash of the EIP712 Domain Separator Schema\n bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"address verifyingContract\",\n \")\"\n ));\n\n // Hash of the EIP712 Domain Separator data\n // solhint-disable-next-line var-name-mixedcase\n bytes32 public EIP712_DOMAIN_HASH;\n\n constructor ()\n public\n {\n EIP712_DOMAIN_HASH = keccak256(abi.encodePacked(\n EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n keccak256(bytes(EIP712_DOMAIN_NAME)),\n keccak256(bytes(EIP712_DOMAIN_VERSION)),\n bytes32(address(this))\n ));\n }\n\n /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.\n /// @param hashStruct The EIP712 hash struct.\n /// @return EIP712 hash applied to this EIP712 Domain.\n function hashEIP712Message(bytes32 hashStruct)\n internal\n view\n returns (bytes32 result)\n {\n bytes32 eip712DomainHash = EIP712_DOMAIN_HASH;\n\n // Assembly for more efficient computing:\n // keccak256(abi.encodePacked(\n // EIP191_HEADER,\n // EIP712_DOMAIN_HASH,\n // hashStruct \n // ));\n\n assembly {\n // Load free memory pointer\n let memPtr := mload(64)\n\n mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header\n mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash\n mstore(add(memPtr, 34), hashStruct) // Hash of struct\n\n // Compute hash\n result := keccak256(memPtr, 66)\n }\n return result;\n }\n}\n", - "@0x/contracts-libs/contracts/libs/LibFillResults.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\nimport \"@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol\";\n\n\ncontract LibFillResults is\n SafeMath\n{\n struct FillResults {\n uint256 makerAssetFilledAmount; // Total amount of makerAsset(s) filled.\n uint256 takerAssetFilledAmount; // Total amount of takerAsset(s) filled.\n uint256 makerFeePaid; // Total amount of ZRX paid by maker(s) to feeRecipient(s).\n uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).\n }\n\n struct MatchedFillResults {\n FillResults left; // Amounts filled and fees paid of left order.\n FillResults right; // Amounts filled and fees paid of right order.\n uint256 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.\n }\n\n /// @dev Adds properties of both FillResults instances.\n /// Modifies the first FillResults instance specified.\n /// @param totalFillResults Fill results instance that will be added onto.\n /// @param singleFillResults Fill results instance that will be added to totalFillResults.\n function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)\n internal\n pure\n {\n totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);\n totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);\n totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);\n totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);\n }\n}\n", - "@0x/contracts-utils/contracts/utils/SafeMath/SafeMath.sol": "pragma solidity 0.4.24;\n\n\ncontract SafeMath {\n\n function safeMul(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n if (a == 0) {\n return 0;\n }\n uint256 c = a * b;\n require(\n c / a == b,\n \"UINT256_OVERFLOW\"\n );\n return c;\n }\n\n function safeDiv(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n uint256 c = a / b;\n return c;\n }\n\n function safeSub(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n require(\n b <= a,\n \"UINT256_UNDERFLOW\"\n );\n return a - b;\n }\n\n function safeAdd(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n uint256 c = a + b;\n require(\n c >= a,\n \"UINT256_OVERFLOW\"\n );\n return c;\n }\n\n function max64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min64(uint64 a, uint64 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\n }\n\n function max256(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n return a >= b ? a : b;\n }\n\n function min256(uint256 a, uint256 b)\n internal\n pure\n returns (uint256)\n {\n return a < b ? a : b;\n }\n}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/IMatchOrders.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibFillResults.sol\";\n\n\ncontract IMatchOrders {\n\n /// @dev Match two complementary orders that have a profitable spread.\n /// Each order is filled at their respective price point. However, the calculations are\n /// carried out as though the orders are both being filled at the right order's price point.\n /// The profit made by the left order goes to the taker (who matched the two orders).\n /// @param leftOrder First order to match.\n /// @param rightOrder Second order to match.\n /// @param leftSignature Proof that order was created by the left maker.\n /// @param rightSignature Proof that order was created by the right maker.\n /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.\n function matchOrders(\n LibOrder.Order memory leftOrder,\n LibOrder.Order memory rightOrder,\n bytes memory leftSignature,\n bytes memory rightSignature\n )\n public\n returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/ISignatureValidator.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract ISignatureValidator {\n\n /// @dev Approves a hash on-chain using any valid signature type.\n /// After presigning a hash, the preSign signature type will become valid for that hash and signer.\n /// @param signerAddress Address that should have signed the given hash.\n /// @param signature Proof that the hash has been signed by signer.\n function preSign(\n bytes32 hash,\n address signerAddress,\n bytes signature\n )\n external;\n \n /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.\n /// @param validatorAddress Address of Validator contract.\n /// @param approval Approval or disapproval of Validator contract.\n function setSignatureValidatorApproval(\n address validatorAddress,\n bool approval\n )\n external;\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signerAddress Address of signer.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n address signerAddress,\n bytes memory signature\n )\n public\n view\n returns (bool isValid);\n}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/ITransactions.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\npragma solidity 0.4.24;\n\n\ncontract ITransactions {\n\n /// @dev Executes an exchange method call in the context of signer.\n /// @param salt Arbitrary number to ensure uniqueness of transaction hash.\n /// @param signerAddress Address of transaction signer.\n /// @param data AbiV2 encoded calldata.\n /// @param signature Proof of signer transaction by signer.\n function executeTransaction(\n uint256 salt,\n address signerAddress,\n bytes data,\n bytes signature\n )\n external;\n}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/IAssetProxyDispatcher.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract IAssetProxyDispatcher {\n\n /// @dev Registers an asset proxy to its asset proxy id.\n /// Once an asset proxy is registered, it cannot be unregistered.\n /// @param assetProxy Address of new asset proxy to register.\n function registerAssetProxy(address assetProxy)\n external;\n\n /// @dev Gets an asset proxy.\n /// @param assetProxyId Id of the asset proxy.\n /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.\n function getAssetProxy(bytes4 assetProxyId)\n external\n view\n returns (address);\n}\n", - "@0x/contracts-interfaces/contracts/protocol/Exchange/IWrapperFunctions.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-libs/contracts/libs/LibOrder.sol\";\nimport \"@0x/contracts-libs/contracts/libs/LibFillResults.sol\";\n\n\ncontract IWrapperFunctions {\n\n /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.\n /// @param order LibOrder.Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signature Proof that order has been created by maker.\n function fillOrKillOrder(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\n /// @param order LibOrder.Order struct containing order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signature Proof that order has been created by maker.\n /// @return Amounts filled and fees paid by maker and taker.\n function fillOrderNoThrow(\n LibOrder.Order memory order,\n uint256 takerAssetFillAmount,\n bytes memory signature\n )\n public\n returns (LibFillResults.FillResults memory fillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function batchFillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrKill.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function batchFillOrKillOrders(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Fills an order with specified parameters and ECDSA signature.\n /// Returns false if the transaction would otherwise revert.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function batchFillOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256[] memory takerAssetFillAmounts,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been created by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrders(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n /// Returns false if the transaction would otherwise revert.\n /// @param orders Array of order specifications.\n /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n /// @param signatures Proofs that orders have been signed by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketSellOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256 takerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\n /// @param orders Array of order specifications.\n /// @param makerAssetFillAmount Desired amount of makerAsset to buy.\n /// @param signatures Proofs that orders have been signed by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketBuyOrders(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.\n /// Returns false if the transaction would otherwise revert.\n /// @param orders Array of order specifications.\n /// @param makerAssetFillAmount Desired amount of makerAsset to buy.\n /// @param signatures Proofs that orders have been signed by makers.\n /// @return Amounts filled and fees paid by makers and taker.\n function marketBuyOrdersNoThrow(\n LibOrder.Order[] memory orders,\n uint256 makerAssetFillAmount,\n bytes[] memory signatures\n )\n public\n returns (LibFillResults.FillResults memory totalFillResults);\n\n /// @dev Synchronously cancels multiple orders in a single transaction.\n /// @param orders Array of order specifications.\n function batchCancelOrders(LibOrder.Order[] memory orders)\n public;\n\n /// @dev Fetches information for all passed in orders\n /// @param orders Array of order specifications.\n /// @return Array of OrderInfo instances that correspond to each order.\n function getOrdersInfo(LibOrder.Order[] memory orders)\n public\n view\n returns (LibOrder.OrderInfo[] memory);\n}\n", - "@0x/contracts-tokens/contracts/tokens/ERC20Token/IERC20Token.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\ncontract IERC20Token {\n\n // solhint-disable no-simple-event-func-name\n event Transfer(\n address indexed _from,\n address indexed _to,\n uint256 _value\n );\n\n event Approval(\n address indexed _owner,\n address indexed _spender,\n uint256 _value\n );\n\n /// @dev send `value` token to `to` from `msg.sender`\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return True if transfer was successful\n function transfer(address _to, uint256 _value)\n external\n returns (bool);\n\n /// @dev send `value` token to `to` from `from` on the condition it is approved by `from`\n /// @param _from The address of the sender\n /// @param _to The address of the recipient\n /// @param _value The amount of token to be transferred\n /// @return True if transfer was successful\n function transferFrom(\n address _from,\n address _to,\n uint256 _value\n )\n external\n returns (bool);\n \n /// @dev `msg.sender` approves `_spender` to spend `_value` tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @param _value The amount of wei to be approved for transfer\n /// @return Always true if the call has enough gas to complete execution\n function approve(address _spender, uint256 _value)\n external\n returns (bool);\n\n /// @dev Query total supply of token\n /// @return Total supply of token\n function totalSupply()\n external\n view\n returns (uint256);\n \n /// @param _owner The address from which the balance will be retrieved\n /// @return Balance of owner\n function balanceOf(address _owner)\n external\n view\n returns (uint256);\n\n /// @param _owner The address of the account owning tokens\n /// @param _spender The address of the account able to transfer the tokens\n /// @return Amount of remaining tokens allowed to spent\n function allowance(address _owner, address _spender)\n external\n view\n returns (uint256);\n}\n", - "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity 0.4.24;\n\n\nlibrary LibBytes {\n\n using LibBytes for bytes;\n\n /// @dev Gets the memory address for a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of byte array. This\n /// points to the header of the byte array which contains\n /// the length.\n function rawAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := input\n }\n return memoryAddress;\n }\n \n /// @dev Gets the memory address for the contents of a byte array.\n /// @param input Byte array to lookup.\n /// @return memoryAddress Memory address of the contents of the byte array.\n function contentAddress(bytes memory input)\n internal\n pure\n returns (uint256 memoryAddress)\n {\n assembly {\n memoryAddress := add(input, 32)\n }\n return memoryAddress;\n }\n\n /// @dev Copies `length` bytes from memory location `source` to `dest`.\n /// @param dest memory address to copy bytes to.\n /// @param source memory address to copy bytes from.\n /// @param length number of bytes to copy.\n function memCopy(\n uint256 dest,\n uint256 source,\n uint256 length\n )\n internal\n pure\n {\n if (length < 32) {\n // Handle a partial word by reading destination and masking\n // off the bits we are interested in.\n // This correctly handles overlap, zero lengths and source == dest\n assembly {\n let mask := sub(exp(256, sub(32, length)), 1)\n let s := and(mload(source), not(mask))\n let d := and(mload(dest), mask)\n mstore(dest, or(s, d))\n }\n } else {\n // Skip the O(length) loop when source == dest.\n if (source == dest) {\n return;\n }\n\n // For large copies we copy whole words at a time. The final\n // word is aligned to the end of the range (instead of after the\n // previous) to handle partial words. So a copy will look like this:\n //\n // ####\n // ####\n // ####\n // ####\n //\n // We handle overlap in the source and destination range by\n // changing the copying direction. This prevents us from\n // overwriting parts of source that we still need to copy.\n //\n // This correctly handles source == dest\n //\n if (source > dest) {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because it\n // is easier to compare with in the loop, and these\n // are also the addresses we need for copying the\n // last bytes.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the last 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the last bytes in\n // source already due to overlap.\n let last := mload(sEnd)\n\n // Copy whole words front to back\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} lt(source, sEnd) {} {\n mstore(dest, mload(source))\n source := add(source, 32)\n dest := add(dest, 32)\n }\n \n // Write the last 32 bytes\n mstore(dEnd, last)\n }\n } else {\n assembly {\n // We subtract 32 from `sEnd` and `dEnd` because those\n // are the starting points when copying a word at the end.\n length := sub(length, 32)\n let sEnd := add(source, length)\n let dEnd := add(dest, length)\n\n // Remember the first 32 bytes of source\n // This needs to be done here and not after the loop\n // because we may have overwritten the first bytes in\n // source already due to overlap.\n let first := mload(source)\n\n // Copy whole words back to front\n // We use a signed comparisson here to allow dEnd to become\n // negative (happens when source and dest < 32). Valid\n // addresses in local memory will never be larger than\n // 2**255, so they can be safely re-interpreted as signed.\n // Note: the first check is always true,\n // this could have been a do-while loop.\n // solhint-disable-next-line no-empty-blocks\n for {} slt(dest, dEnd) {} {\n mstore(dEnd, mload(sEnd))\n sEnd := sub(sEnd, 32)\n dEnd := sub(dEnd, 32)\n }\n \n // Write the first 32 bytes\n mstore(dest, first)\n }\n }\n }\n }\n\n /// @dev Returns a slices from a byte array.\n /// @param b The byte array to take a slice from.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n function slice(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\n );\n \n // Create a new bytes structure and copy contents\n result = new bytes(to - from);\n memCopy(\n result.contentAddress(),\n b.contentAddress() + from,\n result.length\n );\n return result;\n }\n \n /// @dev Returns a slice from a byte array without preserving the input.\n /// @param b The byte array to take a slice from. Will be destroyed in the process.\n /// @param from The starting index for the slice (inclusive).\n /// @param to The final index for the slice (exclusive).\n /// @return result The slice containing bytes at indices [from, to)\n /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.\n function sliceDestructive(\n bytes memory b,\n uint256 from,\n uint256 to\n )\n internal\n pure\n returns (bytes memory result)\n {\n require(\n from <= to,\n \"FROM_LESS_THAN_TO_REQUIRED\"\n );\n require(\n to < b.length,\n \"TO_LESS_THAN_LENGTH_REQUIRED\"\n );\n \n // Create a new bytes structure around [from, to) in-place.\n assembly {\n result := add(b, from)\n mstore(result, sub(to, from))\n }\n return result;\n }\n\n /// @dev Pops the last byte off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The byte that was popped off.\n function popLastByte(bytes memory b)\n internal\n pure\n returns (bytes1 result)\n {\n require(\n b.length > 0,\n \"GREATER_THAN_ZERO_LENGTH_REQUIRED\"\n );\n\n // Store last byte.\n result = b[b.length - 1];\n\n assembly {\n // Decrement length of byte array.\n let newLen := sub(mload(b), 1)\n mstore(b, newLen)\n }\n return result;\n }\n\n /// @dev Pops the last 20 bytes off of a byte array by modifying its length.\n /// @param b Byte array that will be modified.\n /// @return The 20 byte address that was popped off.\n function popLast20Bytes(bytes memory b)\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= 20,\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Store last 20 bytes.\n result = readAddress(b, b.length - 20);\n\n assembly {\n // Subtract 20 from byte array length.\n let newLen := sub(mload(b), 20)\n mstore(b, newLen)\n }\n return result;\n }\n\n /// @dev Tests equality of two byte arrays.\n /// @param lhs First byte array to compare.\n /// @param rhs Second byte array to compare.\n /// @return True if arrays are the same. False otherwise.\n function equals(\n bytes memory lhs,\n bytes memory rhs\n )\n internal\n pure\n returns (bool equal)\n {\n // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.\n // We early exit on unequal lengths, but keccak would also correctly\n // handle this.\n return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);\n }\n\n /// @dev Reads an address from a position in a byte array.\n /// @param b Byte array containing an address.\n /// @param index Index in byte array of address.\n /// @return address from byte array.\n function readAddress(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (address result)\n {\n require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Read address from array memory\n assembly {\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 20-byte mask to obtain address\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\n }\n return result;\n }\n\n /// @dev Writes an address into a specific position in a byte array.\n /// @param b Byte array to insert address into.\n /// @param index Index in byte array of address.\n /// @param input Address to put into byte array.\n function writeAddress(\n bytes memory b,\n uint256 index,\n address input\n )\n internal\n pure\n {\n require(\n b.length >= index + 20, // 20 is length of address\n \"GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED\"\n );\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Store address into array memory\n assembly {\n // The address occupies 20 bytes and mstore stores 32 bytes.\n // First fetch the 32-byte word where we'll be storing the address, then\n // apply a mask so we have only the bytes in the word that the address will not occupy.\n // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.\n\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address\n let neighbors := and(\n mload(add(b, index)),\n 0xffffffffffffffffffffffff0000000000000000000000000000000000000000\n )\n \n // Make sure input address is clean.\n // (Solidity does not guarantee this)\n input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)\n\n // Store the neighbors and address into memory\n mstore(add(b, index), xor(input, neighbors))\n }\n }\n\n /// @dev Reads a bytes32 value from a position in a byte array.\n /// @param b Byte array containing a bytes32 value.\n /// @param index Index in byte array of bytes32 value.\n /// @return bytes32 value from byte array.\n function readBytes32(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes32 result)\n {\n require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\n );\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n result := mload(add(b, index))\n }\n return result;\n }\n\n /// @dev Writes a bytes32 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input bytes32 to put into byte array.\n function writeBytes32(\n bytes memory b,\n uint256 index,\n bytes32 input\n )\n internal\n pure\n {\n require(\n b.length >= index + 32,\n \"GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED\"\n );\n\n // Arrays are prefixed by a 256 bit length parameter\n index += 32;\n\n // Read the bytes32 from array memory\n assembly {\n mstore(add(b, index), input)\n }\n }\n\n /// @dev Reads a uint256 value from a position in a byte array.\n /// @param b Byte array containing a uint256 value.\n /// @param index Index in byte array of uint256 value.\n /// @return uint256 value from byte array.\n function readUint256(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (uint256 result)\n {\n result = uint256(readBytes32(b, index));\n return result;\n }\n\n /// @dev Writes a uint256 into a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input uint256 to put into byte array.\n function writeUint256(\n bytes memory b,\n uint256 index,\n uint256 input\n )\n internal\n pure\n {\n writeBytes32(b, index, bytes32(input));\n }\n\n /// @dev Reads an unpadded bytes4 value from a position in a byte array.\n /// @param b Byte array containing a bytes4 value.\n /// @param index Index in byte array of bytes4 value.\n /// @return bytes4 value from byte array.\n function readBytes4(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes4 result)\n {\n require(\n b.length >= index + 4,\n \"GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED\"\n );\n\n // Arrays are prefixed by a 32 byte length field\n index += 32;\n\n // Read the bytes4 from array memory\n assembly {\n result := mload(add(b, index))\n // Solidity does not require us to clean the trailing bytes.\n // We do it anyway\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\n }\n return result;\n }\n\n /// @dev Reads nested bytes from a specific position.\n /// @dev NOTE: the returned value overlaps with the input value.\n /// Both should be treated as immutable.\n /// @param b Byte array containing nested bytes.\n /// @param index Index of nested bytes.\n /// @return result Nested bytes.\n function readBytesWithLength(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes memory result)\n {\n // Read length of nested bytes\n uint256 nestedBytesLength = readUint256(b, index);\n index += 32;\n\n // Assert length of is valid, given\n // length of nested bytes\n require(\n b.length >= index + nestedBytesLength,\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n \n // Return a pointer to the byte array as it exists inside `b`\n assembly {\n result := add(b, index)\n }\n return result;\n }\n\n /// @dev Inserts bytes at a specific position in a byte array.\n /// @param b Byte array to insert into.\n /// @param index Index in byte array of .\n /// @param input bytes to insert.\n function writeBytesWithLength(\n bytes memory b,\n uint256 index,\n bytes memory input\n )\n internal\n pure\n {\n // Assert length of is valid, given\n // length of input\n require(\n b.length >= index + 32 + input.length, // 32 bytes to store length\n \"GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED\"\n );\n\n // Copy into \n memCopy(\n b.contentAddress() + index,\n input.rawAddress(), // includes length of \n input.length + 32 // +32 bytes to store length\n );\n }\n\n /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.\n /// @param dest Byte array that will be overwritten with source bytes.\n /// @param source Byte array to copy onto dest bytes.\n function deepCopyBytes(\n bytes memory dest,\n bytes memory source\n )\n internal\n pure\n {\n uint256 sourceLen = source.length;\n // Dest length must be >= source length, or some bytes would not be copied.\n require(\n dest.length >= sourceLen,\n \"GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED\"\n );\n memCopy(\n dest.contentAddress(),\n source.contentAddress(),\n sourceLen\n );\n }\n}\n" - }, - "sourceTreeHashHex": "0x4be45134ccdebcf000c4e09f6aed69041411babf993cfba6871e9ad73369122f", - "compiler": { - "name": "solc", - "version": "soljson-v0.4.24+commit.e67f0147.js", - "settings": { - "optimizer": { - "enabled": true, - "runs": 1000000 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode.object", - "evm.bytecode.sourceMap", - "evm.deployedBytecode.object", - "evm.deployedBytecode.sourceMap" - ] - } - } - } - }, - "networks": {} -} \ No newline at end of file + "networks": {} +} -- cgit From 5da748a062043b46133a2dbce248a756bbefce12 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 20 Dec 2018 19:40:16 -0800 Subject: Progress on dutch auction wrapper. Need to add auction data decoding to it. --- .../contract-wrappers/src/contract_wrappers.ts | 2 +- .../src/contract_wrappers/dutch_auction_wrapper.ts | 74 +++++++++++++++++++++- .../test/dutch_auction_wrapper_test.ts | 46 ++++++++------ 3 files changed, 99 insertions(+), 23 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index 396505866..3728d58d3 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -149,7 +149,7 @@ export class ContractWrappers { this.dutchAuction = new DutchAuctionWrapper( this._web3Wrapper, config.networkId, - contractAddresses.orderValidator, + contractAddresses.dutchAuction, ); } /** diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index 500e7a63d..fee543c3b 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -21,9 +21,13 @@ import { OrderTransactionOpts } from '../types'; import { ContractWrapper } from './contract_wrapper'; import { ExchangeWrapperError } from '../types'; +import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; +import { constants } from 'zlib'; + export class DutchAuctionWrapper extends ContractWrapper { public abi: ContractAbi = DutchAuction.compilerOutput.abi; public address: string; + private _exchangeAddress: string; private _dutchAuctionContractIfExists?: DutchAuctionContract; /** * Instantiate DutchAuctionWrapper @@ -35,10 +39,12 @@ export class DutchAuctionWrapper extends ContractWrapper { constructor( web3Wrapper: Web3Wrapper, networkId: number, - address: string, + address?: string, + exchangeAddress?: string, ) { super(web3Wrapper, networkId); - this.address = address; + this.address = this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).dutchAuction : address; + this._exchangeAddress = _.isUndefined(exchangeAddress) ? _getDefaultContractAddresses(networkId).exchange : exchangeAddress; } /** * Matches the buy and sell orders at an amount given the following: the current block time, the auction @@ -110,6 +116,8 @@ export class DutchAuctionWrapper extends ContractWrapper { // type assertions assert.doesConformToSchema('sellOrder', sellOrder, schemas.signedOrderSchema); // get contract + console.log(sellOrder); + console.log(await this._getDutchAuctionContractAsync()); const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); // call contract const afterAuctionDetails = await dutchAuctionInstance.getAuctionDetails.callAsync(sellOrder); @@ -128,6 +136,66 @@ export class DutchAuctionWrapper extends ContractWrapper { this._dutchAuctionContractIfExists = contractInstance; return this._dutchAuctionContractIfExists; } + + public async createSignedSellOrderAsync( + auctionBeginTimeSections: BigNumber, + auctionBeginAmount: BigNumber, + auctionEndAmount: BigNumber, + acutionEndTime: BigNumber, + makerAssetData: string, + takerAssetData: string, + makerAddress: string, + takerAddress: string, + takerFillableAmount: BigNumber, + senderAddress?: string, + makerFee?: BigNumber, + takerFee?: BigNumber, + feeRecipientAddress?: string, + ): Promise { + console.log(`asdasd`); + const makerAssetAmount = auctionEndAmount; + const makerAssetDataWithAuctionDetails = DutchAuctionWrapper.encodeDutchAuctionAssetData(makerAssetData, auctionBeginTimeSections, auctionBeginAmount); + const signedOrder = await orderFactory.createSignedOrderAsync( + this._web3Wrapper.getProvider(), + makerAddress, + makerAssetAmount, + makerAssetDataWithAuctionDetails, + takerFillableAmount, + takerAssetData, + this._exchangeAddress, + { + takerAddress, + senderAddress, + makerFee, + takerFee, + feeRecipientAddress, + expirationTimeSeconds: acutionEndTime, + }, + ); + //console.log(signedOrder); + return signedOrder; + } + + public async createSignedBuyOrderAsync(sellOrder: SignedOrder, buyerAddress: string, senderAddress?: string, makerFee?: BigNumber, takerFee?: BigNumber, feeRecipientAddress?: string): Promise { + const signedOrder = await orderFactory.createSignedOrderAsync( + this._web3Wrapper.getProvider(), + buyerAddress, + sellOrder.takerAssetAmount.times(2), // change this to decode value from auction @TODO -- add decode above for this. + sellOrder.takerAssetData, + sellOrder.makerAssetAmount, + sellOrder.makerAssetData, + sellOrder.exchangeAddress, + { + senderAddress, + makerFee, + takerFee, + feeRecipientAddress, + expirationTimeSeconds: sellOrder.expirationTimeSeconds, + }, + ); + // console.log(signedOrder); + return signedOrder; + } /** * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex * encoded assetData string, containing information both about the asset being traded and the @@ -138,6 +206,7 @@ export class DutchAuctionWrapper extends ContractWrapper { * @return The hex encoded assetData string. */ public static encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string { + // console.log(`yoooo`, assetData); const assetDataBuffer = ethUtil.toBuffer(assetData); const abiEncodedAuctionData = (ethAbi as any).rawEncode( ['uint256', 'uint256'], @@ -145,6 +214,7 @@ export class DutchAuctionWrapper extends ContractWrapper { ); const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); + // console.log(`GREFG --- `, abiEncodedAuctionData); const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); return dutchAuctionData; }; diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index ad8b3bd31..bfc4e0a58 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -16,6 +16,7 @@ import { provider, web3Wrapper } from './utils/web3_wrapper'; import { getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; import { DutchAuction } from '@0x/contract-artifacts'; import { DutchAuctionWrapper } from '../src/contract_wrappers/dutch_auction_wrapper'; +import { Web3Wrapper } from '@0x/web3-wrapper'; chaiSetup.configure(); const expect = chai.expect; @@ -23,7 +24,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); // tslint:disable:custom-no-magic-numbers describe.only('DutchAuctionWrapper', () => { - const fillableAmount = new BigNumber(5); + const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; let fillScenarios: FillScenarios; @@ -32,10 +33,9 @@ describe.only('DutchAuctionWrapper', () => { let userAddresses: string[]; let makerAddress: string; let takerAddress: string; + let buyerAddress: string; let makerTokenAddress: string; let takerTokenAddress: string; - let makerAssetData: string; - let takerAssetData: string; let buyOrder: SignedOrder; let sellOrder: SignedOrder; let makerTokenAssetData: string; @@ -63,40 +63,44 @@ describe.only('DutchAuctionWrapper', () => { contractWrappers.erc20Proxy.address, contractWrappers.erc721Proxy.address, ); - [, makerAddress, takerAddress] = userAddresses; + [, makerAddress, takerAddress, buyerAddress] = userAddresses; [makerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); takerTokenAddress = contractWrappers.forwarder.etherTokenAddress; + console.log(`B`); // construct asset data for tokens being swapped [makerTokenAssetData, takerTokenAssetData] = [ assetDataUtils.encodeERC20AssetData(makerTokenAddress), assetDataUtils.encodeERC20AssetData(takerTokenAddress), ]; + console.log(`C`); // encode auction details in maker asset data const auctionBeginAmount = fillableAmount; const currentBlockTimestamp = await getLatestBlockTimestampAsync(); const auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); - makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( + /* makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( makerTokenAssetData, auctionBeginTimeSeconds, auctionBeginAmount - ); - takerAssetData = takerTokenAssetData; + );*/ + console.log(`C2`); // create sell / buy orders for auction // note that the maker/taker asset datas are swapped in the `buyOrder` - sellOrder = await fillScenarios.createFillableSignedOrderAsync( - makerAssetData, - takerAssetData, - makerAddress, - constants.NULL_ADDRESS, + sellOrder = await contractWrappers.dutchAuction.createSignedSellOrderAsync( + auctionBeginTimeSeconds, + fillableAmount.times(2), fillableAmount, - ); - buyOrder = await fillScenarios.createFillableSignedOrderAsync( - takerAssetData, - makerAssetData, + new BigNumber(currentBlockTimestamp + tenMinutesInSeconds), + makerTokenAssetData, + takerTokenAssetData, makerAddress, constants.NULL_ADDRESS, fillableAmount, ); + buyOrder = await contractWrappers.dutchAuction.createSignedBuyOrderAsync( + sellOrder, + buyerAddress, + ); + console.log(`CD`); }); after(async () => { await blockchainLifecycle.revertAsync(); @@ -109,8 +113,10 @@ describe.only('DutchAuctionWrapper', () => { }); describe('#matchOrdersAsync', () => { it('should match two orders', async () => { - const txHash = await contractWrappers.dutchAuction.matchOrdersAsync(buyOrder, sellOrder, takerAddress); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + console.log(await contractWrappers.dutchAuction.getAuctionDetailsAsync(sellOrder)); + + // const txHash = await contractWrappers.dutchAuction.matchOrdersAsync(buyOrder, sellOrder, takerAddress, {gasLimit: 1000000}); + //await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); it('should throw when invalid transaction and shouldValidate is true', async () => { // request match with bad buy/sell orders @@ -130,7 +136,7 @@ describe.only('DutchAuctionWrapper', () => { }); describe('#getAuctionDetailsAsync', () => { - it('should be worth the begin price at the begining of the auction', async () => { + /*it('should be worth the begin price at the begining of the auction', async () => { // setup auction details const auctionBeginAmount = fillableAmount; const currentBlockTimestamp = await getLatestBlockTimestampAsync(); @@ -151,6 +157,6 @@ describe.only('DutchAuctionWrapper', () => { expect(auctionDetails.currentTimeSeconds).to.be.bignumber.lte(auctionBeginTimeSeconds); expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionBeginAmount); expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount); - }); + });*/ }); }); -- cgit From 7203ca90cf9bff2f7accf5fe2ee7da5764d0dac3 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 16:11:59 -0800 Subject: all dutchie wrapper tests passing --- .../src/contract_wrappers/dutch_auction_wrapper.ts | 94 +++++++--------------- .../test/dutch_auction_wrapper_test.ts | 90 +++++++++++---------- 2 files changed, 76 insertions(+), 108 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index fee543c3b..5896617fc 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -7,7 +7,7 @@ import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { DutchAuctionDetails, SignedOrder } from '@0x/types'; import { ContractAbi } from 'ethereum-types'; import { Web3Wrapper } from '@0x/web3-wrapper'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, abiUtils } from '@0x/utils'; import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; import ethAbi = require('ethereumjs-abi'); @@ -21,8 +21,7 @@ import { OrderTransactionOpts } from '../types'; import { ContractWrapper } from './contract_wrapper'; import { ExchangeWrapperError } from '../types'; -import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; -import { constants } from 'zlib'; +import { assetDataUtils, AssetData } from '@0x/order-utils'; export class DutchAuctionWrapper extends ContractWrapper { public abi: ContractAbi = DutchAuction.compilerOutput.abi; @@ -74,6 +73,10 @@ export class DutchAuctionWrapper extends ContractWrapper { sellOrder.takerAssetData !== buyOrder.makerAssetData ) { throw new Error(ExchangeWrapperError.AssetDataMismatch); + } else { + // Smart contracts assigns the asset data from the left order to the right one so we can save gas on reducing the size of call data + //rightSignedOrder.makerAssetData = '0x'; + // rightSignedOrder.takerAssetData = '0x'; } // get contract const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); @@ -136,66 +139,6 @@ export class DutchAuctionWrapper extends ContractWrapper { this._dutchAuctionContractIfExists = contractInstance; return this._dutchAuctionContractIfExists; } - - public async createSignedSellOrderAsync( - auctionBeginTimeSections: BigNumber, - auctionBeginAmount: BigNumber, - auctionEndAmount: BigNumber, - acutionEndTime: BigNumber, - makerAssetData: string, - takerAssetData: string, - makerAddress: string, - takerAddress: string, - takerFillableAmount: BigNumber, - senderAddress?: string, - makerFee?: BigNumber, - takerFee?: BigNumber, - feeRecipientAddress?: string, - ): Promise { - console.log(`asdasd`); - const makerAssetAmount = auctionEndAmount; - const makerAssetDataWithAuctionDetails = DutchAuctionWrapper.encodeDutchAuctionAssetData(makerAssetData, auctionBeginTimeSections, auctionBeginAmount); - const signedOrder = await orderFactory.createSignedOrderAsync( - this._web3Wrapper.getProvider(), - makerAddress, - makerAssetAmount, - makerAssetDataWithAuctionDetails, - takerFillableAmount, - takerAssetData, - this._exchangeAddress, - { - takerAddress, - senderAddress, - makerFee, - takerFee, - feeRecipientAddress, - expirationTimeSeconds: acutionEndTime, - }, - ); - //console.log(signedOrder); - return signedOrder; - } - - public async createSignedBuyOrderAsync(sellOrder: SignedOrder, buyerAddress: string, senderAddress?: string, makerFee?: BigNumber, takerFee?: BigNumber, feeRecipientAddress?: string): Promise { - const signedOrder = await orderFactory.createSignedOrderAsync( - this._web3Wrapper.getProvider(), - buyerAddress, - sellOrder.takerAssetAmount.times(2), // change this to decode value from auction @TODO -- add decode above for this. - sellOrder.takerAssetData, - sellOrder.makerAssetAmount, - sellOrder.makerAssetData, - sellOrder.exchangeAddress, - { - senderAddress, - makerFee, - takerFee, - feeRecipientAddress, - expirationTimeSeconds: sellOrder.expirationTimeSeconds, - }, - ); - // console.log(signedOrder); - return signedOrder; - } /** * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex * encoded assetData string, containing information both about the asset being traded and the @@ -206,7 +149,6 @@ export class DutchAuctionWrapper extends ContractWrapper { * @return The hex encoded assetData string. */ public static encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string { - // console.log(`yoooo`, assetData); const assetDataBuffer = ethUtil.toBuffer(assetData); const abiEncodedAuctionData = (ethAbi as any).rawEncode( ['uint256', 'uint256'], @@ -218,4 +160,28 @@ export class DutchAuctionWrapper extends ContractWrapper { const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); return dutchAuctionData; }; + /** + * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex + * encoded assetData string, containing information both about the asset being traded and the + * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. + * @param dutchAuctionData Hex encoded assetData string for the asset being auctioned. + * @return + */ + public static decodeDutchAuctionData(dutchAuctionData: string): [AssetData, BigNumber, BigNumber] { + const dutchAuctionDataBuffer = ethUtil.toBuffer(dutchAuctionData); + // Decode asset data + const assetDataBuffer = dutchAuctionDataBuffer.slice(0, dutchAuctionDataBuffer.byteLength - 64); + const assetDataHex = ethUtil.bufferToHex(assetDataBuffer); + const assetData = assetDataUtils.decodeAssetDataOrThrow(assetDataHex); + // Decode auction details + const dutchAuctionDetailsBuffer = dutchAuctionDataBuffer.slice(dutchAuctionDataBuffer.byteLength - 64); + const [beginTimeSecondsAsBN, beginAmountAsBN] = ethAbi.rawDecode( + ['uint256', 'uint256'], + dutchAuctionDetailsBuffer + ); + const beginTimeSeconds = new BigNumber(`0x${beginTimeSecondsAsBN.toString()}`); + const beginAmount = new BigNumber(`0x${beginAmountAsBN.toString()}`); + console.log(beginAmount); + return [assetData, beginTimeSeconds, beginAmount]; + }; } diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index bfc4e0a58..f548e3ff8 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -1,7 +1,7 @@ import { BlockchainLifecycle } from '@0x/dev-utils'; import { FillScenarios } from '@0x/fill-scenarios'; import { assetDataUtils } from '@0x/order-utils'; -import { SignedOrder } from '@0x/types'; +import { RevertReason, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; import 'mocha'; @@ -18,13 +18,19 @@ import { DutchAuction } from '@0x/contract-artifacts'; import { DutchAuctionWrapper } from '../src/contract_wrappers/dutch_auction_wrapper'; import { Web3Wrapper } from '@0x/web3-wrapper'; +import { DutchAuctionUtils } from './utils/dutch_auction_utils'; + +import { + expectTransactionFailedAsync, +} from '@0x/contracts-test-utils'; + chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); // tslint:disable:custom-no-magic-numbers describe.only('DutchAuctionWrapper', () => { - const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); + const fillableAmount = new BigNumber(2);//Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; let fillScenarios: FillScenarios; @@ -33,13 +39,16 @@ describe.only('DutchAuctionWrapper', () => { let userAddresses: string[]; let makerAddress: string; let takerAddress: string; - let buyerAddress: string; let makerTokenAddress: string; let takerTokenAddress: string; let buyOrder: SignedOrder; let sellOrder: SignedOrder; let makerTokenAssetData: string; let takerTokenAssetData: string; + let auctionBeginTimeSeconds: BigNumber; + let auctionBeginAmount: BigNumber; + let auctionEndTimeSeconds: BigNumber; + let auctionEndAmount: BigNumber; before(async () => { console.log(`BEOGIN DEPLOYINH`); const contractAddresses = await migrateOnceAsync(); @@ -63,9 +72,8 @@ describe.only('DutchAuctionWrapper', () => { contractWrappers.erc20Proxy.address, contractWrappers.erc721Proxy.address, ); - [, makerAddress, takerAddress, buyerAddress] = userAddresses; - [makerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); - takerTokenAddress = contractWrappers.forwarder.etherTokenAddress; + [, makerAddress, takerAddress] = userAddresses; + [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); console.log(`B`); // construct asset data for tokens being swapped [makerTokenAssetData, takerTokenAssetData] = [ @@ -74,31 +82,40 @@ describe.only('DutchAuctionWrapper', () => { ]; console.log(`C`); // encode auction details in maker asset data - const auctionBeginAmount = fillableAmount; + auctionEndAmount = fillableAmount; + auctionBeginAmount = auctionEndAmount.times(2); const currentBlockTimestamp = await getLatestBlockTimestampAsync(); - const auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); + auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); + auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); /* makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( makerTokenAssetData, auctionBeginTimeSeconds, auctionBeginAmount );*/ console.log(`C2`); + // Create template orders from + + // create sell / buy orders for auction // note that the maker/taker asset datas are swapped in the `buyOrder` - sellOrder = await contractWrappers.dutchAuction.createSignedSellOrderAsync( + + const coinbase = userAddresses[0]; + const dutchAuctionUtils = new DutchAuctionUtils(web3Wrapper, coinbase, exchangeContractAddress, contractWrappers.erc20Proxy.address); + sellOrder = await dutchAuctionUtils.createSignedSellOrderAsync( auctionBeginTimeSeconds, - fillableAmount.times(2), - fillableAmount, - new BigNumber(currentBlockTimestamp + tenMinutesInSeconds), + auctionBeginAmount, + auctionEndAmount, + auctionEndTimeSeconds, makerTokenAssetData, takerTokenAssetData, makerAddress, constants.NULL_ADDRESS, - fillableAmount, + auctionEndAmount, ); - buyOrder = await contractWrappers.dutchAuction.createSignedBuyOrderAsync( + console.log(`ASDS`); + buyOrder = await dutchAuctionUtils.createSignedBuyOrderAsync( sellOrder, - buyerAddress, + takerAddress, ); console.log(`CD`); }); @@ -113,17 +130,15 @@ describe.only('DutchAuctionWrapper', () => { }); describe('#matchOrdersAsync', () => { it('should match two orders', async () => { - console.log(await contractWrappers.dutchAuction.getAuctionDetailsAsync(sellOrder)); - - // const txHash = await contractWrappers.dutchAuction.matchOrdersAsync(buyOrder, sellOrder, takerAddress, {gasLimit: 1000000}); - //await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const txHash = await contractWrappers.dutchAuction.matchOrdersAsync(buyOrder, sellOrder, takerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); it('should throw when invalid transaction and shouldValidate is true', async () => { // request match with bad buy/sell orders const badSellOrder = buyOrder; const badBuyOrder = sellOrder; - return expect( - await contractWrappers.dutchAuction.matchOrdersAsync( + return expectTransactionFailedAsync( + contractWrappers.dutchAuction.matchOrdersAsync( badBuyOrder, badSellOrder, takerAddress, @@ -131,32 +146,19 @@ describe.only('DutchAuctionWrapper', () => { shouldValidate: true, }, ), - ).to.be.rejectedWith('COMPLETE_FILL_FAILED'); + RevertReason.InvalidAssetData + ); }); }); describe('#getAuctionDetailsAsync', () => { - /*it('should be worth the begin price at the begining of the auction', async () => { - // setup auction details - const auctionBeginAmount = fillableAmount; - const currentBlockTimestamp = await getLatestBlockTimestampAsync(); - const auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); - const makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( - makerTokenAssetData, - auctionBeginTimeSeconds, - auctionBeginAmount - ); - const order = await fillScenarios.createFillableSignedOrderAsync( - makerAssetData, - takerAssetData, - makerAddress, - constants.NULL_ADDRESS, - fillableAmount, - ); - const auctionDetails = await contractWrappers.dutchAuction.getAuctionDetailsAsync(order); - expect(auctionDetails.currentTimeSeconds).to.be.bignumber.lte(auctionBeginTimeSeconds); - expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionBeginAmount); - expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount); - });*/ + it('should be worth the begin price at the begining of the auction', async () => { + // get auction details + const auctionDetails = await contractWrappers.dutchAuction.getAuctionDetailsAsync(sellOrder); + // run some basic sanity checks on the return value + expect(auctionDetails.beginTimeSeconds, 'auctionDetails.beginTimeSeconds').to.be.bignumber.equal(auctionBeginTimeSeconds); + expect(auctionDetails.beginAmount, 'auctionDetails.beginAmount').to.be.bignumber.equal(auctionBeginAmount); + expect(auctionDetails.endTimeSeconds, 'auctionDetails.endTimeSeconds').to.be.bignumber.equal(auctionEndTimeSeconds); + }); }); }); -- cgit From 0432212a346aa761c54b5a9159a7e61e0c2f9b9a Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 16:40:07 -0800 Subject: dutch wrapper tests working --- .../src/contract_wrappers/dutch_auction_wrapper.ts | 24 +++++------- packages/contract-wrappers/src/types.ts | 12 ++++++ .../test/dutch_auction_wrapper_test.ts | 43 +++------------------- 3 files changed, 27 insertions(+), 52 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index 5896617fc..dea759962 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -19,9 +19,9 @@ import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; import { OrderTransactionOpts } from '../types'; import { ContractWrapper } from './contract_wrapper'; -import { ExchangeWrapperError } from '../types'; +import { DutchAuctionWrapperError, DutchAuctionData } from '../types'; -import { assetDataUtils, AssetData } from '@0x/order-utils'; +import { assetDataUtils } from '@0x/order-utils'; export class DutchAuctionWrapper extends ContractWrapper { public abi: ContractAbi = DutchAuction.compilerOutput.abi; @@ -72,11 +72,7 @@ export class DutchAuctionWrapper extends ContractWrapper { sellOrder.makerAssetData !== buyOrder.takerAssetData || sellOrder.takerAssetData !== buyOrder.makerAssetData ) { - throw new Error(ExchangeWrapperError.AssetDataMismatch); - } else { - // Smart contracts assigns the asset data from the left order to the right one so we can save gas on reducing the size of call data - //rightSignedOrder.makerAssetData = '0x'; - // rightSignedOrder.takerAssetData = '0x'; + throw new Error(DutchAuctionWrapperError.AssetDataMismatch); } // get contract const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); @@ -119,8 +115,6 @@ export class DutchAuctionWrapper extends ContractWrapper { // type assertions assert.doesConformToSchema('sellOrder', sellOrder, schemas.signedOrderSchema); // get contract - console.log(sellOrder); - console.log(await this._getDutchAuctionContractAsync()); const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); // call contract const afterAuctionDetails = await dutchAuctionInstance.getAuctionDetails.callAsync(sellOrder); @@ -156,7 +150,6 @@ export class DutchAuctionWrapper extends ContractWrapper { ); const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); - // console.log(`GREFG --- `, abiEncodedAuctionData); const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); return dutchAuctionData; }; @@ -165,9 +158,9 @@ export class DutchAuctionWrapper extends ContractWrapper { * encoded assetData string, containing information both about the asset being traded and the * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. * @param dutchAuctionData Hex encoded assetData string for the asset being auctioned. - * @return + * @return An object containing the auction asset, auction begin time and auction begin amount. */ - public static decodeDutchAuctionData(dutchAuctionData: string): [AssetData, BigNumber, BigNumber] { + public static decodeDutchAuctionData(dutchAuctionData: string): DutchAuctionData { const dutchAuctionDataBuffer = ethUtil.toBuffer(dutchAuctionData); // Decode asset data const assetDataBuffer = dutchAuctionDataBuffer.slice(0, dutchAuctionDataBuffer.byteLength - 64); @@ -181,7 +174,10 @@ export class DutchAuctionWrapper extends ContractWrapper { ); const beginTimeSeconds = new BigNumber(`0x${beginTimeSecondsAsBN.toString()}`); const beginAmount = new BigNumber(`0x${beginAmountAsBN.toString()}`); - console.log(beginAmount); - return [assetData, beginTimeSeconds, beginAmount]; + return { + assetData, + beginTimeSeconds, + beginAmount + }; }; } diff --git a/packages/contract-wrappers/src/types.ts b/packages/contract-wrappers/src/types.ts index 14d4649ae..f23587c20 100644 --- a/packages/contract-wrappers/src/types.ts +++ b/packages/contract-wrappers/src/types.ts @@ -14,6 +14,8 @@ import { BigNumber } from '@0x/utils'; import { BlockParam, ContractEventArg, DecodedLogArgs, LogEntryEvent, LogWithDecodedArgs } from 'ethereum-types'; +import { AssetData } from '@0x/order-utils'; + export enum ExchangeWrapperError { AssetDataMismatch = 'ASSET_DATA_MISMATCH', } @@ -206,3 +208,13 @@ export interface BalanceAndAllowance { balance: BigNumber; allowance: BigNumber; } + +export enum DutchAuctionWrapperError { + AssetDataMismatch = 'ASSET_DATA_MISMATCH', +} + +export interface DutchAuctionData { + assetData: AssetData; + beginTimeSeconds: BigNumber; + beginAmount: BigNumber; +} diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index f548e3ff8..697554dd1 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -1,12 +1,11 @@ import { BlockchainLifecycle } from '@0x/dev-utils'; -import { FillScenarios } from '@0x/fill-scenarios'; import { assetDataUtils } from '@0x/order-utils'; import { RevertReason, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; import 'mocha'; -import { ContractWrappers, OrderStatus } from '../src'; +import { ContractWrappers } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; @@ -14,10 +13,6 @@ import { migrateOnceAsync } from './utils/migrate'; import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; import { getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; -import { DutchAuction } from '@0x/contract-artifacts'; -import { DutchAuctionWrapper } from '../src/contract_wrappers/dutch_auction_wrapper'; -import { Web3Wrapper } from '@0x/web3-wrapper'; - import { DutchAuctionUtils } from './utils/dutch_auction_utils'; import { @@ -33,9 +28,7 @@ describe.only('DutchAuctionWrapper', () => { const fillableAmount = new BigNumber(2);//Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; - let fillScenarios: FillScenarios; let exchangeContractAddress: string; - let zrxTokenAddress: string; let userAddresses: string[]; let makerAddress: string; let takerAddress: string; @@ -50,7 +43,7 @@ describe.only('DutchAuctionWrapper', () => { let auctionEndTimeSeconds: BigNumber; let auctionEndAmount: BigNumber; before(async () => { - console.log(`BEOGIN DEPLOYINH`); + // setup contract wrappers & addresses const contractAddresses = await migrateOnceAsync(); await blockchainLifecycle.startAsync(); const config = { @@ -58,47 +51,23 @@ describe.only('DutchAuctionWrapper', () => { contractAddresses, blockPollingIntervalMs: 10, }; - contractWrappers = new ContractWrappers(provider, config); - console.log(`DEPLOYINH`); exchangeContractAddress = contractWrappers.exchange.address; userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - zrxTokenAddress = contractWrappers.exchange.zrxTokenAddress; - fillScenarios = new FillScenarios( - provider, - userAddresses, - zrxTokenAddress, - exchangeContractAddress, - contractWrappers.erc20Proxy.address, - contractWrappers.erc721Proxy.address, - ); [, makerAddress, takerAddress] = userAddresses; [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); - console.log(`B`); // construct asset data for tokens being swapped [makerTokenAssetData, takerTokenAssetData] = [ assetDataUtils.encodeERC20AssetData(makerTokenAddress), assetDataUtils.encodeERC20AssetData(takerTokenAddress), ]; - console.log(`C`); - // encode auction details in maker asset data + // setup auction details in maker asset data auctionEndAmount = fillableAmount; auctionBeginAmount = auctionEndAmount.times(2); const currentBlockTimestamp = await getLatestBlockTimestampAsync(); auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); - /* makerAssetData = DutchAuctionWrapper.encodeDutchAuctionAssetData( - makerTokenAssetData, - auctionBeginTimeSeconds, - auctionBeginAmount - );*/ - console.log(`C2`); - // Create template orders from - - - // create sell / buy orders for auction - // note that the maker/taker asset datas are swapped in the `buyOrder` - + // create auction orders const coinbase = userAddresses[0]; const dutchAuctionUtils = new DutchAuctionUtils(web3Wrapper, coinbase, exchangeContractAddress, contractWrappers.erc20Proxy.address); sellOrder = await dutchAuctionUtils.createSignedSellOrderAsync( @@ -112,12 +81,10 @@ describe.only('DutchAuctionWrapper', () => { constants.NULL_ADDRESS, auctionEndAmount, ); - console.log(`ASDS`); buyOrder = await dutchAuctionUtils.createSignedBuyOrderAsync( sellOrder, takerAddress, ); - console.log(`CD`); }); after(async () => { await blockchainLifecycle.revertAsync(); @@ -152,7 +119,7 @@ describe.only('DutchAuctionWrapper', () => { }); describe('#getAuctionDetailsAsync', () => { - it('should be worth the begin price at the begining of the auction', async () => { + it('should get auction details', async () => { // get auction details const auctionDetails = await contractWrappers.dutchAuction.getAuctionDetailsAsync(sellOrder); // run some basic sanity checks on the return value -- cgit From b249a50d8f0054328a901525af6316133ed64023 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 16:40:11 -0800 Subject: ran prettier --- .../src/contract_wrappers/dutch_auction_wrapper.ts | 33 +++++++++--------- .../test/dutch_auction_wrapper_test.ts | 39 +++++++++++----------- 2 files changed, 35 insertions(+), 37 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index dea759962..b7cdff670 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -1,14 +1,10 @@ -import { artifacts as protocolArtifacts } from '@0x/contracts-protocol'; import { DutchAuctionContract } from '@0x/abi-gen-wrappers'; import { DutchAuction } from '@0x/contract-artifacts'; -import { LogDecoder } from '@0x/contracts-test-utils'; -import { artifacts as tokensArtifacts } from '@0x/contracts-tokens'; import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { DutchAuctionDetails, SignedOrder } from '@0x/types'; import { ContractAbi } from 'ethereum-types'; import { Web3Wrapper } from '@0x/web3-wrapper'; import { BigNumber, abiUtils } from '@0x/utils'; -import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; import ethAbi = require('ethereumjs-abi'); import { schemas } from '@0x/json-schemas'; @@ -35,15 +31,14 @@ export class DutchAuctionWrapper extends ContractWrapper { * @param address The address of the Dutch Auction contract. If undefined, will * default to the known address corresponding to the networkId. */ - constructor( - web3Wrapper: Web3Wrapper, - networkId: number, - address?: string, - exchangeAddress?: string, - ) { + constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string, exchangeAddress?: string) { super(web3Wrapper, networkId); - this.address = this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).dutchAuction : address; - this._exchangeAddress = _.isUndefined(exchangeAddress) ? _getDefaultContractAddresses(networkId).exchange : exchangeAddress; + this.address = this.address = _.isUndefined(address) + ? _getDefaultContractAddresses(networkId).dutchAuction + : address; + this._exchangeAddress = _.isUndefined(exchangeAddress) + ? _getDefaultContractAddresses(networkId).exchange + : exchangeAddress; } /** * Matches the buy and sell orders at an amount given the following: the current block time, the auction @@ -142,7 +137,11 @@ export class DutchAuctionWrapper extends ContractWrapper { * @param beginAmount Starting amount being sold in the dutch auction. * @return The hex encoded assetData string. */ - public static encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string { + public static encodeDutchAuctionAssetData( + assetData: string, + beginTimeSeconds: BigNumber, + beginAmount: BigNumber, + ): string { const assetDataBuffer = ethUtil.toBuffer(assetData); const abiEncodedAuctionData = (ethAbi as any).rawEncode( ['uint256', 'uint256'], @@ -152,7 +151,7 @@ export class DutchAuctionWrapper extends ContractWrapper { const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); return dutchAuctionData; - }; + } /** * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex * encoded assetData string, containing information both about the asset being traded and the @@ -170,14 +169,14 @@ export class DutchAuctionWrapper extends ContractWrapper { const dutchAuctionDetailsBuffer = dutchAuctionDataBuffer.slice(dutchAuctionDataBuffer.byteLength - 64); const [beginTimeSecondsAsBN, beginAmountAsBN] = ethAbi.rawDecode( ['uint256', 'uint256'], - dutchAuctionDetailsBuffer + dutchAuctionDetailsBuffer, ); const beginTimeSeconds = new BigNumber(`0x${beginTimeSecondsAsBN.toString()}`); const beginAmount = new BigNumber(`0x${beginAmountAsBN.toString()}`); return { assetData, beginTimeSeconds, - beginAmount + beginAmount, }; - }; + } } diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index 697554dd1..fa5ef41fd 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -15,9 +15,7 @@ import { provider, web3Wrapper } from './utils/web3_wrapper'; import { getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; import { DutchAuctionUtils } from './utils/dutch_auction_utils'; -import { - expectTransactionFailedAsync, -} from '@0x/contracts-test-utils'; +import { expectTransactionFailedAsync } from '@0x/contracts-test-utils'; chaiSetup.configure(); const expect = chai.expect; @@ -25,7 +23,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); // tslint:disable:custom-no-magic-numbers describe.only('DutchAuctionWrapper', () => { - const fillableAmount = new BigNumber(2);//Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); + const fillableAmount = new BigNumber(2); //Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; let exchangeContractAddress: string; @@ -69,7 +67,12 @@ describe.only('DutchAuctionWrapper', () => { auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); // create auction orders const coinbase = userAddresses[0]; - const dutchAuctionUtils = new DutchAuctionUtils(web3Wrapper, coinbase, exchangeContractAddress, contractWrappers.erc20Proxy.address); + const dutchAuctionUtils = new DutchAuctionUtils( + web3Wrapper, + coinbase, + exchangeContractAddress, + contractWrappers.erc20Proxy.address, + ); sellOrder = await dutchAuctionUtils.createSignedSellOrderAsync( auctionBeginTimeSeconds, auctionBeginAmount, @@ -81,10 +84,7 @@ describe.only('DutchAuctionWrapper', () => { constants.NULL_ADDRESS, auctionEndAmount, ); - buyOrder = await dutchAuctionUtils.createSignedBuyOrderAsync( - sellOrder, - takerAddress, - ); + buyOrder = await dutchAuctionUtils.createSignedBuyOrderAsync(sellOrder, takerAddress); }); after(async () => { await blockchainLifecycle.revertAsync(); @@ -105,15 +105,10 @@ describe.only('DutchAuctionWrapper', () => { const badSellOrder = buyOrder; const badBuyOrder = sellOrder; return expectTransactionFailedAsync( - contractWrappers.dutchAuction.matchOrdersAsync( - badBuyOrder, - badSellOrder, - takerAddress, - { - shouldValidate: true, - }, - ), - RevertReason.InvalidAssetData + contractWrappers.dutchAuction.matchOrdersAsync(badBuyOrder, badSellOrder, takerAddress, { + shouldValidate: true, + }), + RevertReason.InvalidAssetData, ); }); }); @@ -123,9 +118,13 @@ describe.only('DutchAuctionWrapper', () => { // get auction details const auctionDetails = await contractWrappers.dutchAuction.getAuctionDetailsAsync(sellOrder); // run some basic sanity checks on the return value - expect(auctionDetails.beginTimeSeconds, 'auctionDetails.beginTimeSeconds').to.be.bignumber.equal(auctionBeginTimeSeconds); + expect(auctionDetails.beginTimeSeconds, 'auctionDetails.beginTimeSeconds').to.be.bignumber.equal( + auctionBeginTimeSeconds, + ); expect(auctionDetails.beginAmount, 'auctionDetails.beginAmount').to.be.bignumber.equal(auctionBeginAmount); - expect(auctionDetails.endTimeSeconds, 'auctionDetails.endTimeSeconds').to.be.bignumber.equal(auctionEndTimeSeconds); + expect(auctionDetails.endTimeSeconds, 'auctionDetails.endTimeSeconds').to.be.bignumber.equal( + auctionEndTimeSeconds, + ); }); }); }); -- cgit From cb1bfa0f9790706bf9ce08aad0bf8fd9e2621ce9 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:04:17 -0800 Subject: ran prettier + added changelog entry for contract wrappers --- packages/contract-wrappers/CHANGELOG.json | 10 ++++++++++ .../src/contract_wrappers/dutch_auction_wrapper.ts | 8 ++------ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 581fbdee1..dadba6190 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,6 +1,16 @@ [ { "version": "4.2.0", + "changes": [ + { + "note": + "Added Dutch Auction wrapper", + "pr": 1465 + } + ] + }, + { + "version": "4.1.4", "changes": [ { "note": "Add support for Trust Wallet signature denial error" diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index b7cdff670..bb1e89555 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -4,7 +4,7 @@ import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { DutchAuctionDetails, SignedOrder } from '@0x/types'; import { ContractAbi } from 'ethereum-types'; import { Web3Wrapper } from '@0x/web3-wrapper'; -import { BigNumber, abiUtils } from '@0x/utils'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import ethAbi = require('ethereumjs-abi'); import { schemas } from '@0x/json-schemas'; @@ -22,7 +22,6 @@ import { assetDataUtils } from '@0x/order-utils'; export class DutchAuctionWrapper extends ContractWrapper { public abi: ContractAbi = DutchAuction.compilerOutput.abi; public address: string; - private _exchangeAddress: string; private _dutchAuctionContractIfExists?: DutchAuctionContract; /** * Instantiate DutchAuctionWrapper @@ -31,14 +30,11 @@ export class DutchAuctionWrapper extends ContractWrapper { * @param address The address of the Dutch Auction contract. If undefined, will * default to the known address corresponding to the networkId. */ - constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string, exchangeAddress?: string) { + constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { super(web3Wrapper, networkId); this.address = this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).dutchAuction : address; - this._exchangeAddress = _.isUndefined(exchangeAddress) - ? _getDefaultContractAddresses(networkId).exchange - : exchangeAddress; } /** * Matches the buy and sell orders at an amount given the following: the current block time, the auction -- cgit From 06139cbfe59a1a00524de097b7e7fe5364c8d1c0 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:05:47 -0800 Subject: Added dutch auction utils to contract-wrappers --- .../test/utils/dutch_auction_utils.ts | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 packages/contract-wrappers/test/utils/dutch_auction_utils.ts (limited to 'packages') diff --git a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts new file mode 100644 index 000000000..9cff1930d --- /dev/null +++ b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts @@ -0,0 +1,144 @@ +import { DummyERC20TokenContract, DummyERC721TokenContract, ExchangeContract } from '@0x/abi-gen-wrappers'; +import { SignedOrder } from '@0x/types'; +import * as artifacts from '@0x/contract-artifacts'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; + +import { DutchAuctionWrapper } from '../../src/contract_wrappers/dutch_auction_wrapper'; +import { constants } from './constants'; +import { assetDataUtils } from '@0x/order-utils'; + +export class DutchAuctionUtils { + private _web3Wrapper: Web3Wrapper; + private _coinbase: string; + private _exchangeAddress: string; + private _erc20ProxyAddress: string; + + constructor(web3Wrapper: Web3Wrapper, coinbase: string, exchangeAddress: string, erc20ProxyAddress: string) { + this._web3Wrapper = web3Wrapper; + this._coinbase = coinbase; + this._exchangeAddress = exchangeAddress; + this._erc20ProxyAddress = erc20ProxyAddress; + } + public async createSignedSellOrderAsync( + auctionBeginTimeSections: BigNumber, + auctionBeginAmount: BigNumber, + auctionEndAmount: BigNumber, + acutionEndTime: BigNumber, + makerAssetData: string, + takerAssetData: string, + makerAddress: string, + takerAddress: string, + takerFillableAmount: BigNumber, + senderAddress?: string, + makerFee?: BigNumber, + takerFee?: BigNumber, + feeRecipientAddress?: string, + ): Promise { + console.log(`asdasd`); + const makerAssetAmount = auctionEndAmount; + const makerAssetDataWithAuctionDetails = DutchAuctionWrapper.encodeDutchAuctionAssetData( + makerAssetData, + auctionBeginTimeSections, + auctionBeginAmount, + ); + const signedOrder = await orderFactory.createSignedOrderAsync( + this._web3Wrapper.getProvider(), + makerAddress, + makerAssetAmount, + makerAssetDataWithAuctionDetails, + takerFillableAmount, + takerAssetData, + this._exchangeAddress, + { + takerAddress, + senderAddress, + makerFee, + takerFee, + feeRecipientAddress, + expirationTimeSeconds: acutionEndTime, + }, + ); + const erc20AssetData = assetDataUtils.decodeERC20AssetData(makerAssetData); + await this._increaseERC20BalanceAndAllowanceAsync(erc20AssetData.tokenAddress, makerAddress, makerAssetAmount); + return signedOrder; + } + public async createSignedBuyOrderAsync( + sellOrder: SignedOrder, + buyerAddress: string, + senderAddress?: string, + makerFee?: BigNumber, + takerFee?: BigNumber, + feeRecipientAddress?: string, + ): Promise { + const dutchAuctionData = DutchAuctionWrapper.decodeDutchAuctionData(sellOrder.makerAssetData); + const signedOrder = await orderFactory.createSignedOrderAsync( + this._web3Wrapper.getProvider(), + buyerAddress, + dutchAuctionData.beginAmount, + sellOrder.takerAssetData, + sellOrder.makerAssetAmount, + sellOrder.makerAssetData, + sellOrder.exchangeAddress, + { + senderAddress, + makerFee, + takerFee, + feeRecipientAddress, + expirationTimeSeconds: sellOrder.expirationTimeSeconds, + }, + ); + const buyerERC20AssetData = assetDataUtils.decodeERC20AssetData(sellOrder.takerAssetData); + await this._increaseERC20BalanceAndAllowanceAsync( + buyerERC20AssetData.tokenAddress, + buyerAddress, + dutchAuctionData.beginAmount, + ); + return signedOrder; + } + private async _increaseERC20BalanceAndAllowanceAsync( + tokenAddress: string, + address: string, + amount: BigNumber, + ): Promise { + if (amount.isZero() || address === constants.NULL_ADDRESS) { + return; // noop + } + await Promise.all([ + this._increaseERC20BalanceAsync(tokenAddress, address, amount), + this._increaseERC20AllowanceAsync(tokenAddress, address, amount), + ]); + } + private async _increaseERC20BalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise { + const erc20Token = new DummyERC20TokenContract( + artifacts.DummyERC20Token.compilerOutput.abi, + tokenAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + const txHash = await erc20Token.transfer.sendTransactionAsync(address, amount, { + from: this._coinbase, + }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + } + private async _increaseERC20AllowanceAsync( + tokenAddress: string, + address: string, + amount: BigNumber, + ): Promise { + const erc20Token = new DummyERC20TokenContract( + artifacts.DummyERC20Token.compilerOutput.abi, + tokenAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + const oldMakerAllowance = await erc20Token.allowance.callAsync(address, this._erc20ProxyAddress); + const newMakerAllowance = oldMakerAllowance.plus(amount); + + const txHash = await erc20Token.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { + from: address, + }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + } +} -- cgit From 6de3a33f365bc73d9c592e96b0d17c7940297613 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:15:43 -0800 Subject: updated relevant changelogs --- packages/abi-gen-wrappers/CHANGELOG.json | 10 ++++++++++ packages/contract-addresses/CHANGELOG.json | 9 +++++++++ packages/contract-addresses/package.json | 2 +- packages/contract-artifacts/CHANGELOG.json | 9 +++++++++ packages/contract-artifacts/package.json | 2 +- packages/contract-wrappers/package.json | 2 +- packages/migrations/CHANGELOG.json | 9 +++++++++ packages/migrations/package.json | 2 +- packages/types/CHANGELOG.json | 9 +++++++++ packages/types/package.json | 2 +- 10 files changed, 51 insertions(+), 5 deletions(-) (limited to 'packages') diff --git a/packages/abi-gen-wrappers/CHANGELOG.json b/packages/abi-gen-wrappers/CHANGELOG.json index d46e828f4..990d4110f 100644 --- a/packages/abi-gen-wrappers/CHANGELOG.json +++ b/packages/abi-gen-wrappers/CHANGELOG.json @@ -1,4 +1,14 @@ [ + { + "version": "2.1.0", + "changes": [ + { + "note": "Added Dutch Auction Wrapper", + "pr": 1465 + } + ], + "timestamp": 1542821676 + }, { "version": "2.0.2", "changes": [ diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json index 21ffaf510..dd0246fe9 100644 --- a/packages/contract-addresses/CHANGELOG.json +++ b/packages/contract-addresses/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "2.1.0", + "changes": [ + { + "note": "Added entries for Dutch Auction contract", + "pr": 1465 + } + ] + }, { "version": "2.0.0", "changes": [ diff --git a/packages/contract-addresses/package.json b/packages/contract-addresses/package.json index c75ae6efa..c5a133ddf 100644 --- a/packages/contract-addresses/package.json +++ b/packages/contract-addresses/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-addresses", - "version": "2.0.0", + "version": "2.1.0", "engines": { "node": ">=6.12" }, diff --git a/packages/contract-artifacts/CHANGELOG.json b/packages/contract-artifacts/CHANGELOG.json index 03c88e71a..b033943d2 100644 --- a/packages/contract-artifacts/CHANGELOG.json +++ b/packages/contract-artifacts/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "1.2.0", + "changes": [ + { + "pr": 1465, + "note": "Added artifact for Dutch Auction contract" + } + ] + }, { "version": "1.1.2", "changes": [ diff --git a/packages/contract-artifacts/package.json b/packages/contract-artifacts/package.json index 71d887545..b819520c6 100644 --- a/packages/contract-artifacts/package.json +++ b/packages/contract-artifacts/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-artifacts", - "version": "1.1.2", + "version": "1.2.0", "engines": { "node": ">=6.12" }, diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index f3f7301fd..c6921d70b 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-wrappers", - "version": "4.1.3", + "version": "4.2.0", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", diff --git a/packages/migrations/CHANGELOG.json b/packages/migrations/CHANGELOG.json index e7b18f12b..cee64a69f 100644 --- a/packages/migrations/CHANGELOG.json +++ b/packages/migrations/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "2.3.0", + "changes": [ + { + "note": "Added migrations for Dutch Auction contract", + "pr": 1465 + } + ] + }, { "version": "2.2.2", "changes": [ diff --git a/packages/migrations/package.json b/packages/migrations/package.json index 72ffe67b2..9892d7b30 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -1,6 +1,6 @@ { "name": "@0x/migrations", - "version": "2.2.2", + "version": "2.3.0", "engines": { "node": ">=6.12" }, diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index fdb421e79..7094953cb 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "1.5.0", + "changes": [ + { + "note": "Added types for Dutch Auction contract", + "pr": 1465 + } + ] + }, { "version": "1.4.1", "changes": [ diff --git a/packages/types/package.json b/packages/types/package.json index 3c4bb6fe6..75c3b7c63 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@0x/types", - "version": "1.4.1", + "version": "1.5.0", "engines": { "node": ">=6.12" }, -- cgit From bbd48283407540b630a42f7155e97adc4b825e1b Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:21:14 -0800 Subject: removed .only --- packages/contract-wrappers/test/dutch_auction_wrapper_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index fa5ef41fd..16d370cb6 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -22,7 +22,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); // tslint:disable:custom-no-magic-numbers -describe.only('DutchAuctionWrapper', () => { +describe('DutchAuctionWrapper', () => { const fillableAmount = new BigNumber(2); //Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; -- cgit From e83a108c52f9414658cf2ef6eae50eda39d11dd1 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:23:46 -0800 Subject: added dutch auction address for testnets --- packages/contract-addresses/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index 5b8e95174..486b078f7 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -41,7 +41,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b', forwarder: '0x2240dab907db71e64d3e0dba4800c83b5c502d4e', orderValidator: '0x90431a90516ab49af23a0530e04e8c7836e7122f', - dutchAuction: '0x', + dutchAuction: '0x2df6b59309f35ada230ec7d61d7d97355017a1df', }, 4: { exchange: '0xbce0b5f6eb618c565c3e5f5cd69652bbc279f44e', @@ -52,7 +52,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0xe1703da878afcebff5b7624a826902af475b9c03', forwarder: '0x2d40589abbdee84961f3a7656b9af7adb0ee5ab4', orderValidator: '0x0c5173a51e26b29d6126c686756fb9fbef71f762', - dutchAuction: '0x', + dutchAuction: '0xdd7bd6437e67c422879364740ab5855fe3dc41f7', }, 42: { erc20Proxy: '0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e', @@ -63,7 +63,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x2c824d2882baa668e0d5202b1e7f2922278703f8', forwarder: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6', orderValidator: '0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d', - dutchAuction: '0x', + dutchAuction: '0xe11667fb51f34c5367f40d7e379327ce32ee7150', }, // NetworkId 50 represents our Ganache snapshot generated from migrations. 50: { -- cgit From dc940d692fb83bc128be1bab8aa86f53fc699cdd Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:30:40 -0800 Subject: removed timestamp from changelog for abi-gen-wrappers --- packages/abi-gen-wrappers/CHANGELOG.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/abi-gen-wrappers/CHANGELOG.json b/packages/abi-gen-wrappers/CHANGELOG.json index 990d4110f..214920a08 100644 --- a/packages/abi-gen-wrappers/CHANGELOG.json +++ b/packages/abi-gen-wrappers/CHANGELOG.json @@ -6,8 +6,7 @@ "note": "Added Dutch Auction Wrapper", "pr": 1465 } - ], - "timestamp": 1542821676 + ] }, { "version": "2.0.2", -- cgit From 0893614859c9f8c20c295aad162c2e0b7853c415 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 17:33:16 -0800 Subject: removed needless newline on contract-wrappers changelog --- packages/contract-wrappers/CHANGELOG.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index dadba6190..c01e35dcf 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -3,8 +3,7 @@ "version": "4.2.0", "changes": [ { - "note": - "Added Dutch Auction wrapper", + "note": "Added Dutch Auction wrapper", "pr": 1465 } ] -- cgit From d6467d707fdc1797eba4a445e805ccadc1f47872 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Fri, 21 Dec 2018 22:23:21 -0800 Subject: Removed redundant assignment --- .../contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index bb1e89555..f243d55d9 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -32,7 +32,7 @@ export class DutchAuctionWrapper extends ContractWrapper { */ constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { super(web3Wrapper, networkId); - this.address = this.address = _.isUndefined(address) + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).dutchAuction : address; } -- cgit From c6ab380685098dbf3a0a6ee5fae137e816839c2d Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sat, 22 Dec 2018 12:56:52 -0800 Subject: Ran prettier & linter --- packages/contract-wrappers/CHANGELOG.json | 2 +- packages/contract-wrappers/package.json | 2 + .../contract-wrappers/src/contract_wrappers.ts | 2 +- .../src/contract_wrappers/dutch_auction_wrapper.ts | 135 +++++++++++---------- .../test/dutch_auction_wrapper_test.ts | 10 +- .../test/utils/dutch_auction_utils.ts | 18 +-- 6 files changed, 86 insertions(+), 83 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index c01e35dcf..677292030 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -4,7 +4,7 @@ "changes": [ { "note": "Added Dutch Auction wrapper", - "pr": 1465 + "pr": 1465 } ] }, diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index c6921d70b..222cfa622 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -69,6 +69,7 @@ "@0x/assert": "^1.0.20", "@0x/contract-addresses": "^2.0.0", "@0x/contract-artifacts": "^1.1.2", + "@0x/contracts-test-utils": "^1.0.2", "@0x/fill-scenarios": "^1.0.16", "@0x/json-schemas": "^2.1.4", "@0x/order-utils": "^3.0.7", @@ -76,6 +77,7 @@ "@0x/typescript-typings": "^3.0.6", "@0x/utils": "^2.0.8", "@0x/web3-wrapper": "^3.2.1", + "ethereumjs-abi": "0.6.5", "ethereum-types": "^1.1.4", "ethereumjs-blockstream": "6.0.0", "ethereumjs-util": "^5.1.1", diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index 3728d58d3..4e594593e 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -12,6 +12,7 @@ import { Web3Wrapper } from '@0x/web3-wrapper'; import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; +import { DutchAuctionWrapper } from './contract_wrappers/dutch_auction_wrapper'; import { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper'; import { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper'; import { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper'; @@ -20,7 +21,6 @@ import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper'; import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper'; import { ForwarderWrapper } from './contract_wrappers/forwarder_wrapper'; import { OrderValidatorWrapper } from './contract_wrappers/order_validator_wrapper'; -import { DutchAuctionWrapper } from './contract_wrappers/dutch_auction_wrapper'; import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema'; import { ContractWrappersConfig } from './types'; import { assert } from './utils/assert'; diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index f243d55d9..cb0c10187 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -1,28 +1,84 @@ import { DutchAuctionContract } from '@0x/abi-gen-wrappers'; import { DutchAuction } from '@0x/contract-artifacts'; -import { _getDefaultContractAddresses } from '../utils/contract_addresses'; +import { schemas } from '@0x/json-schemas'; +import { assetDataUtils } from '@0x/order-utils'; import { DutchAuctionDetails, SignedOrder } from '@0x/types'; -import { ContractAbi } from 'ethereum-types'; -import { Web3Wrapper } from '@0x/web3-wrapper'; import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { ContractAbi } from 'ethereum-types'; +import * as ethAbi from 'ethereumjs-abi'; +import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; -import ethAbi = require('ethereumjs-abi'); -import { schemas } from '@0x/json-schemas'; -import { assert } from '../utils/assert'; -import ethUtil = require('ethereumjs-util'); import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; -import { OrderTransactionOpts } from '../types'; -import { ContractWrapper } from './contract_wrapper'; -import { DutchAuctionWrapperError, DutchAuctionData } from '../types'; +import { DutchAuctionData, DutchAuctionWrapperError, OrderTransactionOpts } from '../types'; +import { assert } from '../utils/assert'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; -import { assetDataUtils } from '@0x/order-utils'; +import { ContractWrapper } from './contract_wrapper'; export class DutchAuctionWrapper extends ContractWrapper { public abi: ContractAbi = DutchAuction.compilerOutput.abi; public address: string; private _dutchAuctionContractIfExists?: DutchAuctionContract; + /** + * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex + * encoded assetData string, containing information both about the asset being traded and the + * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. + * @param assetData Hex encoded assetData string for the asset being auctioned. + * @param beginTimeSeconds Begin time of the dutch auction. + * @param beginAmount Starting amount being sold in the dutch auction. + * @return The hex encoded assetData string. + */ + public static encodeDutchAuctionAssetData( + assetData: string, + beginTimeSeconds: BigNumber, + beginAmount: BigNumber, + ): string { + const assetDataBuffer = ethUtil.toBuffer(assetData); + const abiEncodedAuctionData = (ethAbi as any).rawEncode( + ['uint256', 'uint256'], + [beginTimeSeconds.toString(), beginAmount.toString()], + ); + const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); + const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); + const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); + return dutchAuctionData; + } + /** + * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex + * encoded assetData string, containing information both about the asset being traded and the + * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. + * @param dutchAuctionData Hex encoded assetData string for the asset being auctioned. + * @return An object containing the auction asset, auction begin time and auction begin amount. + */ + public static decodeDutchAuctionData(dutchAuctionData: string): DutchAuctionData { + const dutchAuctionDataBuffer = ethUtil.toBuffer(dutchAuctionData); + // Decode asset data + const dutchAuctionDataLengthInBytes = 64; + const assetDataBuffer = dutchAuctionDataBuffer.slice( + 0, + dutchAuctionDataBuffer.byteLength - dutchAuctionDataLengthInBytes, + ); + const assetDataHex = ethUtil.bufferToHex(assetDataBuffer); + const assetData = assetDataUtils.decodeAssetDataOrThrow(assetDataHex); + // Decode auction details + const dutchAuctionDetailsBuffer = dutchAuctionDataBuffer.slice( + dutchAuctionDataBuffer.byteLength - dutchAuctionDataLengthInBytes, + ); + const [beginTimeSecondsAsBN, beginAmountAsBN] = ethAbi.rawDecode( + ['uint256', 'uint256'], + dutchAuctionDetailsBuffer, + ); + const beginTimeSeconds = new BigNumber(`0x${beginTimeSecondsAsBN.toString()}`); + const beginAmount = new BigNumber(`0x${beginAmountAsBN.toString()}`); + return { + assetData, + beginTimeSeconds, + beginAmount, + }; + } /** * Instantiate DutchAuctionWrapper * @param web3Wrapper Web3Wrapper instance to use. @@ -30,11 +86,9 @@ export class DutchAuctionWrapper extends ContractWrapper { * @param address The address of the Dutch Auction contract. If undefined, will * default to the known address corresponding to the networkId. */ - constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { + public constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { super(web3Wrapper, networkId); - this.address = _.isUndefined(address) - ? _getDefaultContractAddresses(networkId).dutchAuction - : address; + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).dutchAuction : address; } /** * Matches the buy and sell orders at an amount given the following: the current block time, the auction @@ -124,55 +178,4 @@ export class DutchAuctionWrapper extends ContractWrapper { this._dutchAuctionContractIfExists = contractInstance; return this._dutchAuctionContractIfExists; } - /** - * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex - * encoded assetData string, containing information both about the asset being traded and the - * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. - * @param assetData Hex encoded assetData string for the asset being auctioned. - * @param beginTimeSeconds Begin time of the dutch auction. - * @param beginAmount Starting amount being sold in the dutch auction. - * @return The hex encoded assetData string. - */ - public static encodeDutchAuctionAssetData( - assetData: string, - beginTimeSeconds: BigNumber, - beginAmount: BigNumber, - ): string { - const assetDataBuffer = ethUtil.toBuffer(assetData); - const abiEncodedAuctionData = (ethAbi as any).rawEncode( - ['uint256', 'uint256'], - [beginTimeSeconds.toString(), beginAmount.toString()], - ); - const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); - const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); - const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); - return dutchAuctionData; - } - /** - * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex - * encoded assetData string, containing information both about the asset being traded and the - * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. - * @param dutchAuctionData Hex encoded assetData string for the asset being auctioned. - * @return An object containing the auction asset, auction begin time and auction begin amount. - */ - public static decodeDutchAuctionData(dutchAuctionData: string): DutchAuctionData { - const dutchAuctionDataBuffer = ethUtil.toBuffer(dutchAuctionData); - // Decode asset data - const assetDataBuffer = dutchAuctionDataBuffer.slice(0, dutchAuctionDataBuffer.byteLength - 64); - const assetDataHex = ethUtil.bufferToHex(assetDataBuffer); - const assetData = assetDataUtils.decodeAssetDataOrThrow(assetDataHex); - // Decode auction details - const dutchAuctionDetailsBuffer = dutchAuctionDataBuffer.slice(dutchAuctionDataBuffer.byteLength - 64); - const [beginTimeSecondsAsBN, beginAmountAsBN] = ethAbi.rawDecode( - ['uint256', 'uint256'], - dutchAuctionDetailsBuffer, - ); - const beginTimeSeconds = new BigNumber(`0x${beginTimeSecondsAsBN.toString()}`); - const beginAmount = new BigNumber(`0x${beginAmountAsBN.toString()}`); - return { - assetData, - beginTimeSeconds, - beginAmount, - }; - } } diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index 16d370cb6..4e6ad44e9 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -1,3 +1,4 @@ +import { expectTransactionFailedAsync, getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; import { assetDataUtils } from '@0x/order-utils'; import { RevertReason, SignedOrder } from '@0x/types'; @@ -9,13 +10,10 @@ import { ContractWrappers } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; +import { DutchAuctionUtils } from './utils/dutch_auction_utils'; import { migrateOnceAsync } from './utils/migrate'; import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; -import { getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; -import { DutchAuctionUtils } from './utils/dutch_auction_utils'; - -import { expectTransactionFailedAsync } from '@0x/contracts-test-utils'; chaiSetup.configure(); const expect = chai.expect; @@ -23,7 +21,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); // tslint:disable:custom-no-magic-numbers describe('DutchAuctionWrapper', () => { - const fillableAmount = new BigNumber(2); //Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18); + const fillableAmount = new BigNumber(2); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; let exchangeContractAddress: string; @@ -62,7 +60,7 @@ describe('DutchAuctionWrapper', () => { // setup auction details in maker asset data auctionEndAmount = fillableAmount; auctionBeginAmount = auctionEndAmount.times(2); - const currentBlockTimestamp = await getLatestBlockTimestampAsync(); + const currentBlockTimestamp: number = await getLatestBlockTimestampAsync(); auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); // create auction orders diff --git a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts index 9cff1930d..766fc373a 100644 --- a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts +++ b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts @@ -1,19 +1,20 @@ -import { DummyERC20TokenContract, DummyERC721TokenContract, ExchangeContract } from '@0x/abi-gen-wrappers'; -import { SignedOrder } from '@0x/types'; +import { DummyERC20TokenContract } from '@0x/abi-gen-wrappers'; import * as artifacts from '@0x/contract-artifacts'; +import { assetDataUtils } from '@0x/order-utils'; +import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; +import { SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; -import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; import { DutchAuctionWrapper } from '../../src/contract_wrappers/dutch_auction_wrapper'; + import { constants } from './constants'; -import { assetDataUtils } from '@0x/order-utils'; export class DutchAuctionUtils { - private _web3Wrapper: Web3Wrapper; - private _coinbase: string; - private _exchangeAddress: string; - private _erc20ProxyAddress: string; + private readonly _web3Wrapper: Web3Wrapper; + private readonly _coinbase: string; + private readonly _exchangeAddress: string; + private readonly _erc20ProxyAddress: string; constructor(web3Wrapper: Web3Wrapper, coinbase: string, exchangeAddress: string, erc20ProxyAddress: string) { this._web3Wrapper = web3Wrapper; @@ -36,7 +37,6 @@ export class DutchAuctionUtils { takerFee?: BigNumber, feeRecipientAddress?: string, ): Promise { - console.log(`asdasd`); const makerAssetAmount = auctionEndAmount; const makerAssetDataWithAuctionDetails = DutchAuctionWrapper.encodeDutchAuctionAssetData( makerAssetData, -- cgit From 55e3774480eda205dd14650d9b9f7511f3d03dd6 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sat, 22 Dec 2018 12:59:40 -0800 Subject: Added @todo for including dutch auction addresses once deployed --- packages/contract-addresses/src/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index 486b078f7..04295300c 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -20,6 +20,8 @@ export enum NetworkId { Ganache = 50, } +const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; + const networkToAddresses: { [networkId: number]: ContractAddresses } = { 1: { erc20Proxy: '0x2240dab907db71e64d3e0dba4800c83b5c502d4e', @@ -30,7 +32,8 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6', forwarder: '0x5468a1dc173652ee28d249c271fa9933144746b1', orderValidator: '0x9463e518dea6810309563c81d5266c1b1d149138', - dutchAuction: '0x', + // @todo hysz/dekz: Add mainnet address once deployed. + dutchAuction: NULL_ADDRESS, }, 3: { erc20Proxy: '0xb1408f4c245a23c31b98d2c626777d4c0d766caa', @@ -75,7 +78,8 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x34d402f14d58e001d8efbe6585051bf9706aa064', forwarder: '0xb69e673309512a9d726f87304c6984054f87a93b', orderValidator: '0xe86bb98fcf9bff3512c74589b78fb168200cc546', - dutchAuction: '0x', + // @todo hysz/dekz: Add address once deployed. + dutchAuction: NULL_ADDRESS, }, }; -- cgit From 61a33688264d31be063cd11260d9f37f3774975b Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sat, 22 Dec 2018 13:11:14 -0800 Subject: `afterAuctionDetails` -> `auctionDetails` --- .../contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index cb0c10187..f9eb3c771 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -162,8 +162,8 @@ export class DutchAuctionWrapper extends ContractWrapper { // get contract const dutchAuctionInstance = await this._getDutchAuctionContractAsync(); // call contract - const afterAuctionDetails = await dutchAuctionInstance.getAuctionDetails.callAsync(sellOrder); - return afterAuctionDetails; + const auctionDetails = await dutchAuctionInstance.getAuctionDetails.callAsync(sellOrder); + return auctionDetails; } private async _getDutchAuctionContractAsync(): Promise { if (!_.isUndefined(this._dutchAuctionContractIfExists)) { -- cgit From 77a2ca1ddc9a7dd444822ca3cb38b3679dbd4085 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sat, 22 Dec 2018 13:54:57 -0800 Subject: Minor documentation updates to dutch auction wrapper --- packages/contract-addresses/CHANGELOG.json | 2 +- .../src/contract_wrappers/dutch_auction_wrapper.ts | 15 +++++------ .../test/dutch_auction_wrapper_test.ts | 16 ++++++------ .../test/utils/dutch_auction_utils.ts | 29 ++++++++++++++-------- 4 files changed, 35 insertions(+), 27 deletions(-) (limited to 'packages') diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json index dd0246fe9..ca79290da 100644 --- a/packages/contract-addresses/CHANGELOG.json +++ b/packages/contract-addresses/CHANGELOG.json @@ -3,7 +3,7 @@ "version": "2.1.0", "changes": [ { - "note": "Added entries for Dutch Auction contract", + "note": "Added testnet entries for Dutch Auction contract (kovan,rinkeby,ropsten)", "pr": 1465 } ] diff --git a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts index f9eb3c771..c1aceff47 100644 --- a/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/dutch_auction_wrapper.ts @@ -47,9 +47,9 @@ export class DutchAuctionWrapper extends ContractWrapper { return dutchAuctionData; } /** - * Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex + * Dutch auction details are encoded with the asset data for a 0x order. This function decodes a hex * encoded assetData string, containing information both about the asset being traded and the - * dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order. + * dutch auction. * @param dutchAuctionData Hex encoded assetData string for the asset being auctioned. * @return An object containing the auction asset, auction begin time and auction begin amount. */ @@ -95,10 +95,11 @@ export class DutchAuctionWrapper extends ContractWrapper { * start time and the auction begin amount. The sell order is a an order at the lowest amount * at the end of the auction. Excess from the match is transferred to the seller. * Over time the price moves from beginAmount to endAmount given the current block.timestamp. - * @param buyOrder The Buyer's order. This order is for the current expected price of the auction. - * @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction). - * @param from Address the transaction is being sent from. - * @return Transaction receipt with decoded logs. + * @param buyOrder The Buyer's order. This order is for the current expected price of the auction. + * @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction). + * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied + * Provider provided at instantiation. + * @return Transaction hash. */ public async matchOrdersAsync( buyOrder: SignedOrder, @@ -152,7 +153,7 @@ export class DutchAuctionWrapper extends ContractWrapper { return txHash; } /** - * Calculates the Auction Details for the given order + * Fetches the Auction Details for the given order * @param sellOrder The Seller's order. This order is for the lowest amount (at the end of the auction). * @return The dutch auction details. */ diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index 4e6ad44e9..fb4eb10b4 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -21,7 +21,9 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); // tslint:disable:custom-no-magic-numbers describe('DutchAuctionWrapper', () => { - const fillableAmount = new BigNumber(2); + const makerAssetAmount = new BigNumber(5); + const auctionEndTakerAmount = new BigNumber(10); + const auctionBeginTakerAmount = auctionEndTakerAmount.times(2); const tenMinutesInSeconds = 10 * 60; let contractWrappers: ContractWrappers; let exchangeContractAddress: string; @@ -35,9 +37,7 @@ describe('DutchAuctionWrapper', () => { let makerTokenAssetData: string; let takerTokenAssetData: string; let auctionBeginTimeSeconds: BigNumber; - let auctionBeginAmount: BigNumber; let auctionEndTimeSeconds: BigNumber; - let auctionEndAmount: BigNumber; before(async () => { // setup contract wrappers & addresses const contractAddresses = await migrateOnceAsync(); @@ -58,8 +58,6 @@ describe('DutchAuctionWrapper', () => { assetDataUtils.encodeERC20AssetData(takerTokenAddress), ]; // setup auction details in maker asset data - auctionEndAmount = fillableAmount; - auctionBeginAmount = auctionEndAmount.times(2); const currentBlockTimestamp: number = await getLatestBlockTimestampAsync(); auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp + tenMinutesInSeconds); @@ -73,14 +71,14 @@ describe('DutchAuctionWrapper', () => { ); sellOrder = await dutchAuctionUtils.createSignedSellOrderAsync( auctionBeginTimeSeconds, - auctionBeginAmount, - auctionEndAmount, auctionEndTimeSeconds, + auctionBeginTakerAmount, + auctionEndTakerAmount, + makerAssetAmount, makerTokenAssetData, takerTokenAssetData, makerAddress, constants.NULL_ADDRESS, - auctionEndAmount, ); buyOrder = await dutchAuctionUtils.createSignedBuyOrderAsync(sellOrder, takerAddress); }); @@ -119,7 +117,7 @@ describe('DutchAuctionWrapper', () => { expect(auctionDetails.beginTimeSeconds, 'auctionDetails.beginTimeSeconds').to.be.bignumber.equal( auctionBeginTimeSeconds, ); - expect(auctionDetails.beginAmount, 'auctionDetails.beginAmount').to.be.bignumber.equal(auctionBeginAmount); + expect(auctionDetails.beginAmount, 'auctionDetails.beginAmount').to.be.bignumber.equal(auctionBeginTakerAmount); expect(auctionDetails.endTimeSeconds, 'auctionDetails.endTimeSeconds').to.be.bignumber.equal( auctionEndTimeSeconds, ); diff --git a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts index 766fc373a..380d0588c 100644 --- a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts +++ b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts @@ -24,31 +24,34 @@ export class DutchAuctionUtils { } public async createSignedSellOrderAsync( auctionBeginTimeSections: BigNumber, - auctionBeginAmount: BigNumber, - auctionEndAmount: BigNumber, - acutionEndTime: BigNumber, + acutionEndTimeSeconds: BigNumber, + auctionBeginTakerAssetAmount: BigNumber, + auctionEndTakerAssetAmount: BigNumber, + makerAssetAmount: BigNumber, makerAssetData: string, takerAssetData: string, makerAddress: string, takerAddress: string, - takerFillableAmount: BigNumber, senderAddress?: string, makerFee?: BigNumber, takerFee?: BigNumber, feeRecipientAddress?: string, ): Promise { - const makerAssetAmount = auctionEndAmount; + // Notes on sell order: + // - The `takerAssetAmount` is set to the `auctionEndTakerAssetAmount`, which is the lowest amount the + // the seller can expect to receive + // - The `makerAssetData` is overloaded to include the auction begin time and begin taker asset amount const makerAssetDataWithAuctionDetails = DutchAuctionWrapper.encodeDutchAuctionAssetData( makerAssetData, auctionBeginTimeSections, - auctionBeginAmount, + auctionBeginTakerAssetAmount, ); const signedOrder = await orderFactory.createSignedOrderAsync( this._web3Wrapper.getProvider(), makerAddress, makerAssetAmount, makerAssetDataWithAuctionDetails, - takerFillableAmount, + auctionEndTakerAssetAmount, takerAssetData, this._exchangeAddress, { @@ -57,7 +60,7 @@ export class DutchAuctionUtils { makerFee, takerFee, feeRecipientAddress, - expirationTimeSeconds: acutionEndTime, + expirationTimeSeconds: acutionEndTimeSeconds, }, ); const erc20AssetData = assetDataUtils.decodeERC20AssetData(makerAssetData); @@ -71,8 +74,15 @@ export class DutchAuctionUtils { makerFee?: BigNumber, takerFee?: BigNumber, feeRecipientAddress?: string, + expirationTimeSeconds?: BigNumber, ): Promise { const dutchAuctionData = DutchAuctionWrapper.decodeDutchAuctionData(sellOrder.makerAssetData); + // Notes on buy order: + // - The `makerAssetAmount` is set to `dutchAuctionData.beginAmount`, which is + // the highest amount the buyer would have to pay out at any point during the auction. + // - The `takerAssetAmount` is set to the seller's `makerAssetAmount`, as the buyer + // receives the entire amount being sold by the seller. + // - The `makerAssetData`/`takerAssetData` are reversed from the sell order const signedOrder = await orderFactory.createSignedOrderAsync( this._web3Wrapper.getProvider(), buyerAddress, @@ -86,7 +96,7 @@ export class DutchAuctionUtils { makerFee, takerFee, feeRecipientAddress, - expirationTimeSeconds: sellOrder.expirationTimeSeconds, + expirationTimeSeconds, }, ); const buyerERC20AssetData = assetDataUtils.decodeERC20AssetData(sellOrder.takerAssetData); @@ -135,7 +145,6 @@ export class DutchAuctionUtils { ); const oldMakerAllowance = await erc20Token.allowance.callAsync(address, this._erc20ProxyAddress); const newMakerAllowance = oldMakerAllowance.plus(amount); - const txHash = await erc20Token.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { from: address, }); -- cgit From a00e416a19a5aa7a6d1a615c4886f9d30339c8f6 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sat, 22 Dec 2018 14:50:24 -0800 Subject: ran prettier --- packages/contract-addresses/src/index.ts | 2 +- packages/contract-wrappers/test/dutch_auction_wrapper_test.ts | 4 +++- packages/contract-wrappers/test/utils/dutch_auction_utils.ts | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'packages') diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index 04295300c..19fe45dd3 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -20,7 +20,7 @@ export enum NetworkId { Ganache = 50, } -const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; +const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; const networkToAddresses: { [networkId: number]: ContractAddresses } = { 1: { diff --git a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts index fb4eb10b4..d7a6ca015 100644 --- a/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts +++ b/packages/contract-wrappers/test/dutch_auction_wrapper_test.ts @@ -117,7 +117,9 @@ describe('DutchAuctionWrapper', () => { expect(auctionDetails.beginTimeSeconds, 'auctionDetails.beginTimeSeconds').to.be.bignumber.equal( auctionBeginTimeSeconds, ); - expect(auctionDetails.beginAmount, 'auctionDetails.beginAmount').to.be.bignumber.equal(auctionBeginTakerAmount); + expect(auctionDetails.beginAmount, 'auctionDetails.beginAmount').to.be.bignumber.equal( + auctionBeginTakerAmount, + ); expect(auctionDetails.endTimeSeconds, 'auctionDetails.endTimeSeconds').to.be.bignumber.equal( auctionEndTimeSeconds, ); diff --git a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts index 380d0588c..8e2aef217 100644 --- a/packages/contract-wrappers/test/utils/dutch_auction_utils.ts +++ b/packages/contract-wrappers/test/utils/dutch_auction_utils.ts @@ -38,7 +38,7 @@ export class DutchAuctionUtils { feeRecipientAddress?: string, ): Promise { // Notes on sell order: - // - The `takerAssetAmount` is set to the `auctionEndTakerAssetAmount`, which is the lowest amount the + // - The `takerAssetAmount` is set to the `auctionEndTakerAssetAmount`, which is the lowest amount the // the seller can expect to receive // - The `makerAssetData` is overloaded to include the auction begin time and begin taker asset amount const makerAssetDataWithAuctionDetails = DutchAuctionWrapper.encodeDutchAuctionAssetData( @@ -78,7 +78,7 @@ export class DutchAuctionUtils { ): Promise { const dutchAuctionData = DutchAuctionWrapper.decodeDutchAuctionData(sellOrder.makerAssetData); // Notes on buy order: - // - The `makerAssetAmount` is set to `dutchAuctionData.beginAmount`, which is + // - The `makerAssetAmount` is set to `dutchAuctionData.beginAmount`, which is // the highest amount the buyer would have to pay out at any point during the auction. // - The `takerAssetAmount` is set to the seller's `makerAssetAmount`, as the buyer // receives the entire amount being sold by the seller. -- cgit From ff0093460d50a2078f18192d6dcc75c76d72730c Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 15:39:02 -0800 Subject: Export dutch auction wrapper in 0x.js --- packages/0x.js/src/index.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages') diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index d21df0c01..ae9f4b771 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -4,6 +4,7 @@ export { assetDataUtils, signatureUtils, generatePseudoRandomSalt, orderHashUtil export { ContractWrappers, + DutchAuctionWrapper, ERC20TokenWrapper, ERC721TokenWrapper, EtherTokenWrapper, -- cgit From edb989fbf381201752309a1e2aa5dcf6837b67d0 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 16:04:09 -0800 Subject: export dutch auction wrapper types from 0x.js --- packages/0x.js/src/index.ts | 2 ++ packages/contract-wrappers/src/index.ts | 1 + 2 files changed, 3 insertions(+) (limited to 'packages') diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index ae9f4b771..790e2a97e 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -28,6 +28,7 @@ export { OrderAndTraderInfo, TraderInfo, ValidateOrderFillableOpts, + DutchAuctionData, } from '@0x/contract-wrappers'; export { @@ -89,6 +90,7 @@ export { ObjectMap, OrderRelevantState, Stats, + DutchAuctionDetails, } from '@0x/types'; export { diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 5c64dbbc6..cf0ec405f 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -55,6 +55,7 @@ export { OrderAndTraderInfo, TraderInfo, ValidateOrderFillableOpts, + DutchAuctionData, } from './types'; export { Order, SignedOrder, AssetProxyId } from '@0x/types'; -- cgit From 5f2a7cb78fd8b937bcecf962071d59a08e46dec5 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 16:13:43 -0800 Subject: removed manual updte of package.json version --- packages/contract-addresses/package.json | 2 +- packages/contract-artifacts/package.json | 2 +- packages/contract-wrappers/package.json | 2 +- packages/migrations/package.json | 2 +- packages/types/package.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'packages') diff --git a/packages/contract-addresses/package.json b/packages/contract-addresses/package.json index c5a133ddf..c75ae6efa 100644 --- a/packages/contract-addresses/package.json +++ b/packages/contract-addresses/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-addresses", - "version": "2.1.0", + "version": "2.0.0", "engines": { "node": ">=6.12" }, diff --git a/packages/contract-artifacts/package.json b/packages/contract-artifacts/package.json index b819520c6..71d887545 100644 --- a/packages/contract-artifacts/package.json +++ b/packages/contract-artifacts/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-artifacts", - "version": "1.2.0", + "version": "1.1.2", "engines": { "node": ">=6.12" }, diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 222cfa622..e4de75ab2 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-wrappers", - "version": "4.2.0", + "version": "4.1.3", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", diff --git a/packages/migrations/package.json b/packages/migrations/package.json index 9892d7b30..72ffe67b2 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -1,6 +1,6 @@ { "name": "@0x/migrations", - "version": "2.3.0", + "version": "2.2.2", "engines": { "node": ">=6.12" }, diff --git a/packages/types/package.json b/packages/types/package.json index 75c3b7c63..3c4bb6fe6 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@0x/types", - "version": "1.5.0", + "version": "1.4.1", "engines": { "node": ">=6.12" }, -- cgit From 7ad23ef6dc3c41a4e1babd28f5f78d2b2addbd10 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 16:16:05 -0800 Subject: Added NetworkID 50 address for dutch auction wrapper --- packages/contract-addresses/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/contract-addresses/src/index.ts b/packages/contract-addresses/src/index.ts index 19fe45dd3..d181a1bec 100644 --- a/packages/contract-addresses/src/index.ts +++ b/packages/contract-addresses/src/index.ts @@ -78,8 +78,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = { assetProxyOwner: '0x34d402f14d58e001d8efbe6585051bf9706aa064', forwarder: '0xb69e673309512a9d726f87304c6984054f87a93b', orderValidator: '0xe86bb98fcf9bff3512c74589b78fb168200cc546', - // @todo hysz/dekz: Add address once deployed. - dutchAuction: NULL_ADDRESS, + dutchAuction: '0xdc688d29394a3f1e6f1e5100862776691afaf3d2', }, }; -- cgit From 37b6858869c61f9c29d4f77c2c2857cb9ed7206e Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 16:48:58 -0800 Subject: Hide dutch auction wrapper from docs -- hopefully this will prevent the "must export Web3Wrapper" error from doc generation --- packages/monorepo-scripts/src/doc_gen_configs.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages') diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index 7a14f8664..dfbe98028 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -37,6 +37,7 @@ export const docGenConfigs: DocGenConfigs = { // and getting confused. Any class name in this list will not have it's constructor rendered in our docs. CLASSES_WITH_HIDDEN_CONSTRUCTORS: [ 'AssetBuyer', + 'DutchAuctionWrapper', 'ERC20ProxyWrapper', 'ERC20TokenWrapper', 'ERC721ProxyWrapper', -- cgit From 3c62815fe3d65860175066177c1d0f8d3fe9e314 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 16:54:33 -0800 Subject: added changelog entry for monorepo-scripts --- packages/monorepo-scripts/CHANGELOG.json | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'packages') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json index 428168437..cebe7ec72 100644 --- a/packages/monorepo-scripts/CHANGELOG.json +++ b/packages/monorepo-scripts/CHANGELOG.json @@ -17,6 +17,10 @@ { "note": "Fix a bug when hardcoded CHANGELOG paths cause fetching release notes to fail", "pr": 1311 + }, + { + "note": "Added DutchAuctionWrapper to the CLASSES_WITH_HIDDEN_CONSTRUCTORS array", + "pr": 1465 } ] }, -- cgit From d0a0673694f26a2e9f8e562d335a34cdc1e9c8b2 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 17:14:34 -0800 Subject: Doc generation working for changes by dutch auction wrapper --- packages/contract-wrappers/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index cf0ec405f..bf9c27018 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -58,7 +58,7 @@ export { DutchAuctionData, } from './types'; -export { Order, SignedOrder, AssetProxyId } from '@0x/types'; +export { AssetData, DutchAuctionDetails, ERC20AssetData, ERC721AssetData, Order, SignedOrder, AssetProxyId } from '@0x/types'; export { BlockParamLiteral, -- cgit From e39ae0350b744227bca73001c90101f0b8613193 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sun, 23 Dec 2018 17:29:12 -0800 Subject: Ran prettier --- packages/contract-wrappers/src/index.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index bf9c27018..853194d6f 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -58,7 +58,15 @@ export { DutchAuctionData, } from './types'; -export { AssetData, DutchAuctionDetails, ERC20AssetData, ERC721AssetData, Order, SignedOrder, AssetProxyId } from '@0x/types'; +export { + AssetData, + DutchAuctionDetails, + ERC20AssetData, + ERC721AssetData, + Order, + SignedOrder, + AssetProxyId, +} from '@0x/types'; export { BlockParamLiteral, -- cgit From 04db7f0fae02ef29795d0f65deb71e64b5552233 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Mon, 7 Jan 2019 13:08:44 -0800 Subject: Fixed merge conflict from development --- packages/0x.js/src/index.ts | 1 + packages/contract-wrappers/src/index.ts | 5 ++++- packages/contract-wrappers/src/types.ts | 4 +--- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index 790e2a97e..006e4cf29 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -81,6 +81,7 @@ export { OrderStateInvalid, OrderState, AssetProxyId, + AssetData, SingleAssetData, ERC20AssetData, ERC721AssetData, diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 853194d6f..69bbe3c91 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -60,9 +60,12 @@ export { export { AssetData, - DutchAuctionDetails, ERC20AssetData, ERC721AssetData, + SingleAssetData, + MultiAssetData, + MultiAssetDataWithRecursiveDecoding, + DutchAuctionDetails, Order, SignedOrder, AssetProxyId, diff --git a/packages/contract-wrappers/src/types.ts b/packages/contract-wrappers/src/types.ts index f23587c20..945ca88cd 100644 --- a/packages/contract-wrappers/src/types.ts +++ b/packages/contract-wrappers/src/types.ts @@ -9,13 +9,11 @@ import { WETH9Events, } from '@0x/abi-gen-wrappers'; import { ContractAddresses } from '@0x/contract-addresses'; -import { OrderState, SignedOrder } from '@0x/types'; +import { AssetData, OrderState, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { BlockParam, ContractEventArg, DecodedLogArgs, LogEntryEvent, LogWithDecodedArgs } from 'ethereum-types'; -import { AssetData } from '@0x/order-utils'; - export enum ExchangeWrapperError { AssetDataMismatch = 'ASSET_DATA_MISMATCH', } -- cgit