From 6b03cfd40d720096bf772c2966b1372c0e54bf51 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 12:05:54 -0700 Subject: Add new react and types --- packages/website/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'packages') diff --git a/packages/website/package.json b/packages/website/package.json index 57cc4ce4b..d5157850c 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -42,10 +42,10 @@ "numeral": "^2.0.6", "polished": "^1.9.2", "query-string": "^6.0.0", - "react": "15.6.1", + "react": "^16.4.2", "react-copy-to-clipboard": "^4.2.3", "react-document-title": "^2.0.3", - "react-dom": "15.6.1", + "react-dom": "^16.4.2", "react-helmet": "^5.2.0", "react-popper": "^1.0.0-beta.6", "react-redux": "^5.0.3", @@ -73,9 +73,9 @@ "@types/node": "^8.0.53", "@types/numeral": "^0.0.22", "@types/query-string": "^5.1.0", - "@types/react": "16.3.13", + "@types/react": "^16.4.2", "@types/react-copy-to-clipboard": "^4.2.0", - "@types/react-dom": "^16.0.3", + "@types/react-dom": "^16.0.7", "@types/react-helmet": "^5.0.6", "@types/react-redux": "^4.4.37", "@types/react-router-dom": "^4.0.4", -- cgit v1.2.3 From 48ab151ec2aaf09f325d1118277ae0d78135de88 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 14:20:55 -0700 Subject: Update react and remove tap event plugin [deprecated] --- packages/react-shared/package.json | 4 ++-- packages/website/package.json | 1 - packages/website/ts/index.tsx | 3 --- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 27927bbc8..6f43a9733 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -45,8 +45,8 @@ "is-mobile": "^0.2.2", "lodash": "^4.17.5", "material-ui": "^0.17.1", - "react": "15.6.1", - "react-dom": "15.6.1", + "react": "^16.4.2", + "react-dom": "^16.4.2", "react-highlight": "0xproject/react-highlight", "react-markdown": "^3.2.2", "react-scroll": "0xproject/react-scroll#similar-to-pr-330", diff --git a/packages/website/package.json b/packages/website/package.json index 9eed39572..377ce8bc0 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -51,7 +51,6 @@ "react-redux": "^5.0.3", "react-router-dom": "^4.1.1", "react-scroll": "0xproject/react-scroll#similar-to-pr-330", - "react-tap-event-plugin": "^2.0.1", "react-tooltip": "^3.2.7", "redux": "^3.6.0", "redux-devtools-extension": "^2.13.2", diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx index 981c6f2cb..9e59b00ac 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -3,7 +3,6 @@ import * as React from 'react'; import { render } from 'react-dom'; import { Provider } from 'react-redux'; import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom'; -import * as injectTapEventPlugin from 'react-tap-event-plugin'; import { MetaTags } from 'ts/components/meta_tags'; import { About } from 'ts/containers/about'; import { FAQ } from 'ts/containers/faq'; @@ -17,8 +16,6 @@ import { tradeHistoryStorage } from 'ts/local_storage/trade_history_storage'; import { store } from 'ts/redux/store'; import { WebsiteLegacyPaths, WebsitePaths } from 'ts/types'; import { muiTheme } from 'ts/utils/mui_theme'; -// Polyfills -injectTapEventPlugin(); // Check if we've introduced an update that requires us to clear the tradeHistory local storage entries tradeHistoryStorage.clearIfRequired(); -- cgit v1.2.3 From 374ee2db329aee32e59d487152b2a3b66e25144d Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:05:46 -0700 Subject: Upgrade react in react-docs --- packages/react-docs/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index 47b266e8e..ecd3d955d 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -46,8 +46,8 @@ "compare-versions": "^3.0.1", "lodash": "^4.17.5", "material-ui": "^0.17.1", - "react": "15.6.1", - "react-dom": "15.6.1", + "react": "^16.4.2", + "react-dom": "^16.4.2", "react-markdown": "^3.2.2", "react-scroll": "0xproject/react-scroll#similar-to-pr-330", "react-tooltip": "^3.2.7", -- cgit v1.2.3 From 65120e84e25f70f014bb195539720aa3dc0f8eec Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:11:14 -0700 Subject: Upgrade react-highlight to version that depends on React 16 --- packages/react-shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 6f43a9733..b59a6201e 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -47,7 +47,7 @@ "material-ui": "^0.17.1", "react": "^16.4.2", "react-dom": "^16.4.2", - "react-highlight": "0xproject/react-highlight", + "react-highlight": "0xproject/react-highlight#e5201e6a6bf276d3a6bf4828252c886c386d3666", "react-markdown": "^3.2.2", "react-scroll": "0xproject/react-scroll#similar-to-pr-330", "react-tap-event-plugin": "^2.0.1" -- cgit v1.2.3 From ec96c3bb7740d9bb3743946fd4b5c4d31c653dc7 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:15:55 -0700 Subject: Upgrade react-shared used by website to one that depends on react 16 --- packages/website/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/website/package.json b/packages/website/package.json index 377ce8bc0..abad4ab0c 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -21,7 +21,7 @@ "@0xproject/contract-wrappers": "^0.0.5", "@0xproject/order-utils": "^0.0.9", "@0xproject/react-docs": "^1.0.6", - "@0xproject/react-shared": "^0.2.3", + "@0xproject/react-shared": "^1.0.7", "@0xproject/subproviders": "^2.0.0", "@0xproject/types": "^0.8.1", "@0xproject/typescript-typings": "^0.4.3", -- cgit v1.2.3 From 813b2ca1fb767febdd610200bf6e39b90bfc117d Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:29:22 -0700 Subject: Bump react-highlight in react-shared once more --- packages/react-shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index b59a6201e..6d6c17830 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -47,7 +47,7 @@ "material-ui": "^0.17.1", "react": "^16.4.2", "react-dom": "^16.4.2", - "react-highlight": "0xproject/react-highlight#e5201e6a6bf276d3a6bf4828252c886c386d3666", + "react-highlight": "0xproject/react-highlight#2f40a42e0a3f0ad126f9f42d505b97b603fc7162", "react-markdown": "^3.2.2", "react-scroll": "0xproject/react-scroll#similar-to-pr-330", "react-tap-event-plugin": "^2.0.1" -- cgit v1.2.3 From 641d86cb9833852ef1e1e0fa5b666db0692e30f4 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:40:04 -0700 Subject: Add typescript dependency to typescript-typings (no idea how it was working) --- packages/typescript-typings/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/typescript-typings/package.json b/packages/typescript-typings/package.json index c047a5328..c02613e28 100644 --- a/packages/typescript-typings/package.json +++ b/packages/typescript-typings/package.json @@ -32,7 +32,8 @@ }, "devDependencies": { "copyfiles": "^2.0.0", - "shx": "^0.2.2" + "shx": "^0.2.2", + "typescript": "3.0.1" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From 103e1aa250bc6ce3189aec5ab373f5644c6d4a93 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:45:43 -0700 Subject: Upgrade typescript version used by sra-spec --- packages/sra-spec/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/sra-spec/package.json b/packages/sra-spec/package.json index 706f9f0aa..35b51432f 100644 --- a/packages/sra-spec/package.json +++ b/packages/sra-spec/package.json @@ -52,7 +52,7 @@ "swagger-cli": "^2.1.1", "ts-node": "^7.0.0", "tslint": "5.11.0", - "typescript": "2.7.1" + "typescript": "3.0.1" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From ad161a973e5453ec267510f54d88621517254039 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 15:59:14 -0700 Subject: Change all onTouchTap to onClick --- packages/website/ts/components/dialogs/blockchain_err_dialog.tsx | 2 +- packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx | 4 ++-- packages/website/ts/components/dialogs/ledger_config_dialog.tsx | 2 +- packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx | 2 +- packages/website/ts/components/dialogs/send_dialog.tsx | 4 ++-- .../website/ts/components/dialogs/track_token_confirmation_dialog.tsx | 4 ++-- packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx | 2 +- .../ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx | 2 +- packages/website/ts/components/fill_warning_dialog.tsx | 4 ++-- packages/website/ts/components/generate_order/asset_picker.tsx | 4 ++-- packages/website/ts/components/token_balances.tsx | 2 +- packages/website/ts/components/top_bar/top_bar.tsx | 2 +- packages/website/ts/components/ui/lifecycle_raised_button.tsx | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx index c8e10303f..18c060991 100644 --- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx +++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx @@ -22,7 +22,7 @@ export class BlockchainErrDialog extends React.Component, ]; diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx index 5f4bf8519..f2cfb279a 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -54,8 +54,8 @@ export class EthWethConversionDialog extends React.Component< } public render(): React.ReactNode { const convertDialogActions = [ - , - , + , + , ]; const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH'; return !_.isUndefined(this.props.etherBalanceInWei) ? ( diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx index d2f373d67..fbc6c868b 100644 --- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx +++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx @@ -64,7 +64,7 @@ export class LedgerConfigDialog extends React.Component, + , ]; const dialogTitle = this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address'; diff --git a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx index 41a17fe96..ef295762b 100644 --- a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx +++ b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx @@ -13,7 +13,7 @@ export const PortalDisclaimerDialog = (props: PortalDisclaimerDialogProps) => { ]} + actions={[]} open={props.isOpen} onRequestClose={props.onToggleDialog} autoScrollBodyContent={true} diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx index c1179dbd0..2754b153f 100644 --- a/packages/website/ts/components/dialogs/send_dialog.tsx +++ b/packages/website/ts/components/dialogs/send_dialog.tsx @@ -38,13 +38,13 @@ export class SendDialog extends React.Component, + , , ]; return ( diff --git a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx index 3751ce06f..c8d5af6b6 100644 --- a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx +++ b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx @@ -43,12 +43,12 @@ export class TrackTokenConfirmationDialog extends React.Component< , , ]} open={this.props.isOpen} diff --git a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx index 3ebab03ef..afbb30b82 100644 --- a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx +++ b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx @@ -14,7 +14,7 @@ export const U2fNotSupportedDialog = (props: U2fNotSupportedDialogProps) => { ]} + actions={[]} open={props.isOpen} onRequestClose={props.onToggleDialog} autoScrollBodyContent={true} diff --git a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx index 78b270c1e..cf2c4dda5 100644 --- a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx +++ b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx @@ -14,7 +14,7 @@ export const WrappedEthSectionNoticeDialog = (props: WrappedEthSectionNoticeDial title="Dedicated Wrapped Ether Section" titleStyle={{ fontWeight: 100 }} actions={[ - , + , ]} open={props.isOpen} onRequestClose={props.onToggleDialog} diff --git a/packages/website/ts/components/fill_warning_dialog.tsx b/packages/website/ts/components/fill_warning_dialog.tsx index 45c492221..4821aaabe 100644 --- a/packages/website/ts/components/fill_warning_dialog.tsx +++ b/packages/website/ts/components/fill_warning_dialog.tsx @@ -18,12 +18,12 @@ export const FillWarningDialog = (props: FillWarningDialogProps) => { props.onToggleDialog(didCancel)} // tslint:disable-line:jsx-no-lambda + onClick={() => props.onToggleDialog(didCancel)} // tslint:disable-line:jsx-no-lambda />, props.onToggleDialog(!didCancel)} // tslint:disable-line:jsx-no-lambda + onClick={() => props.onToggleDialog(!didCancel)} // tslint:disable-line:jsx-no-lambda />, ]} open={props.isOpen} diff --git a/packages/website/ts/components/generate_order/asset_picker.tsx b/packages/website/ts/components/generate_order/asset_picker.tsx index 2dca3483f..98aad6c62 100644 --- a/packages/website/ts/components/generate_order/asset_picker.tsx +++ b/packages/website/ts/components/generate_order/asset_picker.tsx @@ -73,12 +73,12 @@ export class AssetPicker extends React.Component, , ], }, diff --git a/packages/website/ts/components/token_balances.tsx b/packages/website/ts/components/token_balances.tsx index 969ef32ff..7e7a8d1fa 100644 --- a/packages/website/ts/components/token_balances.tsx +++ b/packages/website/ts/components/token_balances.tsx @@ -165,7 +165,7 @@ export class TokenBalances extends React.Component, ]; const isTestNetwork = utils.isTestNetwork(this.props.networkId); diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index 9ef8211a9..8580c3a6e 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -410,7 +410,7 @@ export class TopBar extends React.Component { {this.props.translate.get(Key.Blog, Deco.Cap)} - + {this.props.translate.get(Key.Faq, Deco.Cap)} diff --git a/packages/website/ts/components/ui/lifecycle_raised_button.tsx b/packages/website/ts/components/ui/lifecycle_raised_button.tsx index 380fbc77d..0bb99b9d8 100644 --- a/packages/website/ts/components/ui/lifecycle_raised_button.tsx +++ b/packages/website/ts/components/ui/lifecycle_raised_button.tsx @@ -71,7 +71,7 @@ export class LifeCycleRaisedButton extends React.Component ); -- cgit v1.2.3 From 91a9014a50cca8e0d42634666fe409839aeae8cf Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 24 Aug 2018 16:48:48 -0700 Subject: Simplify dropdown component --- packages/website/ts/components/ui/drop_down.tsx | 40 ++++++++++--------------- 1 file changed, 15 insertions(+), 25 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 4d5caef08..752c92e02 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -25,6 +25,7 @@ export interface DropDownProps { interface DropDownState { isDropDownOpen: boolean; + isHovering: boolean; anchorEl?: HTMLInputElement; } @@ -35,11 +36,21 @@ export class DropDown extends React.Component { activateEvent: DropdownMouseEvent.Hover, closeEvent: DropdownMouseEvent.Hover, }; - private _isHovering: boolean; private _popoverCloseCheckIntervalId: number; + public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial { + switch (props.activateEvent) { + case DropdownMouseEvent.Click: + return { isDropDownOpen: state.isDropDownOpen }; + case DropdownMouseEvent.Hover: + return { isDropDownOpen: state.isHovering }; + default: + return {}; + } + } constructor(props: DropDownProps) { super(props); this.state = { + isHovering: false, isDropDownOpen: false, }; } @@ -51,15 +62,6 @@ export class DropDown extends React.Component { public componentWillUnmount(): void { window.clearInterval(this._popoverCloseCheckIntervalId); } - public componentWillReceiveProps(_nextProps: DropDownProps): void { - // HACK: If the popoverContent is updated to a different dimension and the users - // mouse is no longer above it, the dropdown can enter an inconsistent state where - // it believes the user is still hovering over it. In order to remedy this, we - // call hoverOff whenever the dropdown receives updated props. This is a hack - // because it will effectively close the dropdown on any prop update, barring - // dropdowns from having dynamic content. - this._onHoverOff(); - } public render(): React.ReactNode { return (
{ } } private _onHover(event: React.FormEvent): void { - this._isHovering = true; - if (this.props.activateEvent === DropdownMouseEvent.Hover) { - this._checkIfShouldOpenPopover(event); - } + this.setState({ isHovering: true }); } private _onHoverOff(): void { - this._isHovering = false; - } - private _checkIfShouldOpenPopover(event: React.FormEvent): void { - if (this.state.isDropDownOpen) { - return; // noop - } - this.setState({ - isDropDownOpen: true, - anchorEl: event.currentTarget, - }); + this.setState({ isHovering: false }); } private _checkIfShouldClosePopover(): void { if (!this.state.isDropDownOpen) { return; // noop } - if (this.props.closeEvent === DropdownMouseEvent.Hover && !this._isHovering) { + if (this.props.closeEvent === DropdownMouseEvent.Hover && !this.state.isHovering) { this._closePopover(); } } -- cgit v1.2.3 From 5785ec0713c39466b3a6a171f5f0a2d38207b44b Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 27 Aug 2018 18:29:35 -0700 Subject: Have new Popover component working in React 16 --- .../ts/components/top_bar/provider_display.tsx | 2 - packages/website/ts/components/top_bar/top_bar.tsx | 2 - packages/website/ts/components/ui/container.tsx | 8 +-- packages/website/ts/components/ui/drop_down.tsx | 43 ++++++++-------- packages/website/ts/components/ui/overlay.tsx | 2 +- packages/website/ts/components/ui/popover.tsx | 59 ++++++++++++++++++++++ packages/website/ts/components/wallet/wallet.tsx | 2 - packages/website/ts/types.ts | 5 -- 8 files changed, 84 insertions(+), 39 deletions(-) create mode 100644 packages/website/ts/components/ui/popover.tsx (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 806eaeea5..0a5c61776 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -61,8 +61,6 @@ export class ProviderDisplay extends React.Component
diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index 8580c3a6e..3eef17746 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -276,8 +276,6 @@ export class TopBar extends React.Component { { public static defaultProps: Partial = { style: DEFAULT_STYLE, zDepth: 1, - activateEvent: DropdownMouseEvent.Hover, - closeEvent: DropdownMouseEvent.Hover, + activateEvent: DropdownMouseEvent.Click, + closeEvent: DropdownMouseEvent.Click, }; private _popoverCloseCheckIntervalId: number; public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial { @@ -70,24 +69,22 @@ export class DropDown extends React.Component { onMouseLeave={this._onHoverOff.bind(this)} >
{this.props.activeNode}
- -
- {this.props.popoverContent} -
-
+
+ {this.props.popoverContent} +
+ + } ); } diff --git a/packages/website/ts/components/ui/overlay.tsx b/packages/website/ts/components/ui/overlay.tsx index fc7507475..cb68aeca1 100644 --- a/packages/website/ts/components/ui/overlay.tsx +++ b/packages/website/ts/components/ui/overlay.tsx @@ -29,4 +29,4 @@ Overlay.defaultProps = { onClick: _.noop.bind(_), }; -Overlay.displayName = 'Overlay'; +Overlay.displayName = 'Overlay'; \ No newline at end of file diff --git a/packages/website/ts/components/ui/popover.tsx b/packages/website/ts/components/ui/popover.tsx new file mode 100644 index 000000000..66c0ac663 --- /dev/null +++ b/packages/website/ts/components/ui/popover.tsx @@ -0,0 +1,59 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { Placement, Popper, PopperChildrenProps } from 'react-popper'; + +import { colors } from '@0xproject/react-shared'; +import { Container } from 'ts/components/ui/container'; +import { Overlay } from 'ts/components/ui/overlay'; +import { styled } from 'ts/style/theme'; + +export interface PopoverProps { + anchorEl: HTMLInputElement; + placement?: Placement; + onRequestClose?: () => void; + zIndex?: number; +} + +const PopoverContainer = styled.div` + background-color: ${colors.white}; + max-height: 679px; + overflow-y: auto; + border-radius: 2px; +`; + +const defaultPlacement: Placement = 'bottom'; + +export class Popover extends React.Component { + public static defaultProps = { + placement: defaultPlacement, + }; + + public render(): React.ReactNode { + const { anchorEl, placement, zIndex, onRequestClose } = this.props; + const overlayStyleOverrides = { + zIndex, + backgroundColor: 'transparent', + }; + return ( +
+ + + {this._renderPopperChildren.bind(this)} + +
+ ); + } + private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode { + const popperContainerStyleOverrids = { + zIndex: _.isUndefined(this.props.zIndex) ? undefined : this.props.zIndex + 1, + }; + return ( +
+ + {this.props.children} + +
+ ); + } +} diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 6abaa840b..968377010 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -234,8 +234,6 @@ export class Wallet extends React.Component { {!isMobile && } } - anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} - targetOrigin={{ horizontal: 'right', vertical: 'top' }} zDepth={1} activateEvent={DropdownMouseEvent.Click} closeEvent={DropdownMouseEvent.Click} diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index c637171dd..e76fae932 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -492,11 +492,6 @@ export enum Deco { Upper, } -export interface MaterialUIPosition { - vertical: 'bottom' | 'top' | 'center'; - horizontal: 'left' | 'middle' | 'right'; -} - export enum Providers { Parity = 'PARITY', Metamask = 'METAMASK', -- cgit v1.2.3 From ac1640140c9279ac9e8a92d84702a2f84d9165fb Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 13:53:49 -0700 Subject: Enable hovering state for dropdown --- packages/website/ts/components/ui/drop_down.tsx | 13 +++++++------ packages/website/ts/components/ui/popover.tsx | 3 ++- packages/website/ts/components/wallet/wallet.tsx | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 638b29f88..32105d353 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -32,8 +32,8 @@ export class DropDown extends React.Component { public static defaultProps: Partial = { style: DEFAULT_STYLE, zDepth: 1, - activateEvent: DropdownMouseEvent.Click, - closeEvent: DropdownMouseEvent.Click, + activateEvent: DropdownMouseEvent.Hover, + closeEvent: DropdownMouseEvent.Hover, }; private _popoverCloseCheckIntervalId: number; public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial { @@ -77,8 +77,6 @@ export class DropDown extends React.Component { zIndex={this.props.zDepth} >
{this.props.popoverContent} @@ -97,10 +95,13 @@ export class DropDown extends React.Component { } } private _onHover(event: React.FormEvent): void { - this.setState({ isHovering: true }); + this.setState({ + isHovering: true, + anchorEl: event.currentTarget, + }); } private _onHoverOff(): void { - this.setState({ isHovering: false }); + this.setState({ isHovering: false, anchorEl: undefined }); } private _checkIfShouldClosePopover(): void { if (!this.state.isDropDownOpen) { diff --git a/packages/website/ts/components/ui/popover.tsx b/packages/website/ts/components/ui/popover.tsx index 66c0ac663..556e8b110 100644 --- a/packages/website/ts/components/ui/popover.tsx +++ b/packages/website/ts/components/ui/popover.tsx @@ -20,6 +20,7 @@ const PopoverContainer = styled.div` max-height: 679px; overflow-y: auto; border-radius: 2px; + box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; `; const defaultPlacement: Placement = 'bottom'; @@ -37,7 +38,7 @@ export class Popover extends React.Component { }; return (
- + {/* */} {this._renderPopperChildren.bind(this)} diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 968377010..191f3a18a 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -235,6 +235,7 @@ export class Wallet extends React.Component { } zDepth={1} + placement="right-end" activateEvent={DropdownMouseEvent.Click} closeEvent={DropdownMouseEvent.Click} /> -- cgit v1.2.3 From 2d1d14d2e42623d5345b6c1e64e39a87b7c3a223 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:04:34 -0700 Subject: Upgrade material ui to 0.20.0 --- packages/website/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/website/package.json b/packages/website/package.json index abad4ab0c..64e317da9 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -37,7 +37,7 @@ "jsonschema": "^1.2.0", "less": "^2.7.2", "lodash": "^4.17.5", - "material-ui": "^0.17.1", + "material-ui": "^0.20.0", "moment": "2.21.0", "numeral": "^2.0.6", "polished": "^1.9.2", @@ -68,7 +68,7 @@ "@types/find-versions": "^2.0.0", "@types/jsonschema": "^1.1.1", "@types/lodash": "4.14.104", - "@types/material-ui": "0.18.0", + "@types/material-ui": "^0.20.0", "@types/node": "^8.0.53", "@types/numeral": "^0.0.22", "@types/query-string": "^5.1.0", -- cgit v1.2.3 From 8e14e65b60bc4b94ba686c7bb5467bb4a5e2c645 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:07:24 -0700 Subject: Revert "Enable hovering state for dropdown" This reverts commit ac1640140c9279ac9e8a92d84702a2f84d9165fb. --- packages/website/ts/components/ui/drop_down.tsx | 13 ++++++------- packages/website/ts/components/ui/popover.tsx | 3 +-- packages/website/ts/components/wallet/wallet.tsx | 1 - 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 32105d353..638b29f88 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -32,8 +32,8 @@ export class DropDown extends React.Component { public static defaultProps: Partial = { style: DEFAULT_STYLE, zDepth: 1, - activateEvent: DropdownMouseEvent.Hover, - closeEvent: DropdownMouseEvent.Hover, + activateEvent: DropdownMouseEvent.Click, + closeEvent: DropdownMouseEvent.Click, }; private _popoverCloseCheckIntervalId: number; public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial { @@ -77,6 +77,8 @@ export class DropDown extends React.Component { zIndex={this.props.zDepth} >
{this.props.popoverContent} @@ -95,13 +97,10 @@ export class DropDown extends React.Component { } } private _onHover(event: React.FormEvent): void { - this.setState({ - isHovering: true, - anchorEl: event.currentTarget, - }); + this.setState({ isHovering: true }); } private _onHoverOff(): void { - this.setState({ isHovering: false, anchorEl: undefined }); + this.setState({ isHovering: false }); } private _checkIfShouldClosePopover(): void { if (!this.state.isDropDownOpen) { diff --git a/packages/website/ts/components/ui/popover.tsx b/packages/website/ts/components/ui/popover.tsx index 556e8b110..66c0ac663 100644 --- a/packages/website/ts/components/ui/popover.tsx +++ b/packages/website/ts/components/ui/popover.tsx @@ -20,7 +20,6 @@ const PopoverContainer = styled.div` max-height: 679px; overflow-y: auto; border-radius: 2px; - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; `; const defaultPlacement: Placement = 'bottom'; @@ -38,7 +37,7 @@ export class Popover extends React.Component { }; return (
- {/* */} + {this._renderPopperChildren.bind(this)} diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 191f3a18a..968377010 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -235,7 +235,6 @@ export class Wallet extends React.Component { } zDepth={1} - placement="right-end" activateEvent={DropdownMouseEvent.Click} closeEvent={DropdownMouseEvent.Click} /> -- cgit v1.2.3 From de11b62e30270ec72ad42c510989b5698339e590 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:07:28 -0700 Subject: Revert "Have new Popover component working in React 16" This reverts commit 5785ec0713c39466b3a6a171f5f0a2d38207b44b. --- .../ts/components/top_bar/provider_display.tsx | 2 + packages/website/ts/components/top_bar/top_bar.tsx | 2 + packages/website/ts/components/ui/container.tsx | 8 +-- packages/website/ts/components/ui/drop_down.tsx | 43 ++++++++-------- packages/website/ts/components/ui/overlay.tsx | 2 +- packages/website/ts/components/ui/popover.tsx | 59 ---------------------- packages/website/ts/components/wallet/wallet.tsx | 2 + packages/website/ts/types.ts | 5 ++ 8 files changed, 39 insertions(+), 84 deletions(-) delete mode 100644 packages/website/ts/components/ui/popover.tsx (limited to 'packages') diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 0a5c61776..806eaeea5 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -61,6 +61,8 @@ export class ProviderDisplay extends React.Component
diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index 3eef17746..8580c3a6e 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -276,6 +276,8 @@ export class TopBar extends React.Component { { public static defaultProps: Partial = { style: DEFAULT_STYLE, zDepth: 1, - activateEvent: DropdownMouseEvent.Click, - closeEvent: DropdownMouseEvent.Click, + activateEvent: DropdownMouseEvent.Hover, + closeEvent: DropdownMouseEvent.Hover, }; private _popoverCloseCheckIntervalId: number; public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial { @@ -69,22 +70,24 @@ export class DropDown extends React.Component { onMouseLeave={this._onHoverOff.bind(this)} >
{this.props.activeNode}
- {this.state.isDropDownOpen && - +
-
- {this.props.popoverContent} -
- - } + {this.props.popoverContent} +
+
); } diff --git a/packages/website/ts/components/ui/overlay.tsx b/packages/website/ts/components/ui/overlay.tsx index cb68aeca1..fc7507475 100644 --- a/packages/website/ts/components/ui/overlay.tsx +++ b/packages/website/ts/components/ui/overlay.tsx @@ -29,4 +29,4 @@ Overlay.defaultProps = { onClick: _.noop.bind(_), }; -Overlay.displayName = 'Overlay'; \ No newline at end of file +Overlay.displayName = 'Overlay'; diff --git a/packages/website/ts/components/ui/popover.tsx b/packages/website/ts/components/ui/popover.tsx deleted file mode 100644 index 66c0ac663..000000000 --- a/packages/website/ts/components/ui/popover.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { Placement, Popper, PopperChildrenProps } from 'react-popper'; - -import { colors } from '@0xproject/react-shared'; -import { Container } from 'ts/components/ui/container'; -import { Overlay } from 'ts/components/ui/overlay'; -import { styled } from 'ts/style/theme'; - -export interface PopoverProps { - anchorEl: HTMLInputElement; - placement?: Placement; - onRequestClose?: () => void; - zIndex?: number; -} - -const PopoverContainer = styled.div` - background-color: ${colors.white}; - max-height: 679px; - overflow-y: auto; - border-radius: 2px; -`; - -const defaultPlacement: Placement = 'bottom'; - -export class Popover extends React.Component { - public static defaultProps = { - placement: defaultPlacement, - }; - - public render(): React.ReactNode { - const { anchorEl, placement, zIndex, onRequestClose } = this.props; - const overlayStyleOverrides = { - zIndex, - backgroundColor: 'transparent', - }; - return ( -
- - - {this._renderPopperChildren.bind(this)} - -
- ); - } - private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode { - const popperContainerStyleOverrids = { - zIndex: _.isUndefined(this.props.zIndex) ? undefined : this.props.zIndex + 1, - }; - return ( -
- - {this.props.children} - -
- ); - } -} diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 968377010..6abaa840b 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -234,6 +234,8 @@ export class Wallet extends React.Component { {!isMobile && } } + anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} + targetOrigin={{ horizontal: 'right', vertical: 'top' }} zDepth={1} activateEvent={DropdownMouseEvent.Click} closeEvent={DropdownMouseEvent.Click} diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index e76fae932..c637171dd 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -492,6 +492,11 @@ export enum Deco { Upper, } +export interface MaterialUIPosition { + vertical: 'bottom' | 'top' | 'center'; + horizontal: 'left' | 'middle' | 'right'; +} + export enum Providers { Parity = 'PARITY', Metamask = 'METAMASK', -- cgit v1.2.3 From 55fab3d98f8714d09906745922b59afbdc0de00d Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:07:29 -0700 Subject: Revert "Simplify dropdown component" This reverts commit 91a9014a50cca8e0d42634666fe409839aeae8cf. --- packages/website/ts/components/ui/drop_down.tsx | 40 +++++++++++++++---------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 752c92e02..4d5caef08 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -25,7 +25,6 @@ export interface DropDownProps { interface DropDownState { isDropDownOpen: boolean; - isHovering: boolean; anchorEl?: HTMLInputElement; } @@ -36,21 +35,11 @@ export class DropDown extends React.Component { activateEvent: DropdownMouseEvent.Hover, closeEvent: DropdownMouseEvent.Hover, }; + private _isHovering: boolean; private _popoverCloseCheckIntervalId: number; - public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial { - switch (props.activateEvent) { - case DropdownMouseEvent.Click: - return { isDropDownOpen: state.isDropDownOpen }; - case DropdownMouseEvent.Hover: - return { isDropDownOpen: state.isHovering }; - default: - return {}; - } - } constructor(props: DropDownProps) { super(props); this.state = { - isHovering: false, isDropDownOpen: false, }; } @@ -62,6 +51,15 @@ export class DropDown extends React.Component { public componentWillUnmount(): void { window.clearInterval(this._popoverCloseCheckIntervalId); } + public componentWillReceiveProps(_nextProps: DropDownProps): void { + // HACK: If the popoverContent is updated to a different dimension and the users + // mouse is no longer above it, the dropdown can enter an inconsistent state where + // it believes the user is still hovering over it. In order to remedy this, we + // call hoverOff whenever the dropdown receives updated props. This is a hack + // because it will effectively close the dropdown on any prop update, barring + // dropdowns from having dynamic content. + this._onHoverOff(); + } public render(): React.ReactNode { return (
{ } } private _onHover(event: React.FormEvent): void { - this.setState({ isHovering: true }); + this._isHovering = true; + if (this.props.activateEvent === DropdownMouseEvent.Hover) { + this._checkIfShouldOpenPopover(event); + } } private _onHoverOff(): void { - this.setState({ isHovering: false }); + this._isHovering = false; + } + private _checkIfShouldOpenPopover(event: React.FormEvent): void { + if (this.state.isDropDownOpen) { + return; // noop + } + this.setState({ + isDropDownOpen: true, + anchorEl: event.currentTarget, + }); } private _checkIfShouldClosePopover(): void { if (!this.state.isDropDownOpen) { return; // noop } - if (this.props.closeEvent === DropdownMouseEvent.Hover && !this.state.isHovering) { + if (this.props.closeEvent === DropdownMouseEvent.Hover && !this._isHovering) { this._closePopover(); } } -- cgit v1.2.3 From 61a4ae7fc408cb2ee22aaf30ec5eb420ff9f2b03 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:15:54 -0700 Subject: Update material-ui in react-shared --- packages/react-shared/package.json | 2 +- packages/website/package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 6d6c17830..aa542f04f 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -44,7 +44,7 @@ "change-case": "^3.0.2", "is-mobile": "^0.2.2", "lodash": "^4.17.5", - "material-ui": "^0.17.1", + "material-ui": "0.20.0", "react": "^16.4.2", "react-dom": "^16.4.2", "react-highlight": "0xproject/react-highlight#2f40a42e0a3f0ad126f9f42d505b97b603fc7162", diff --git a/packages/website/package.json b/packages/website/package.json index 64e317da9..0a3bec9b8 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -27,6 +27,7 @@ "@0xproject/typescript-typings": "^0.4.3", "@0xproject/utils": "^1.0.6", "@0xproject/web3-wrapper": "^2.0.0", + "@types/material-ui": "^0.20.0", "accounting": "^0.4.1", "basscss": "^8.0.3", "blockies": "^0.0.2", -- cgit v1.2.3 From ac135d55d369e456fbec754707842d5c81795aa3 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:32:15 -0700 Subject: Upgrade material ui in react-docs --- packages/react-docs/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index ad35b8e13..4ad0b0c19 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -37,7 +37,7 @@ "@0xproject/react-shared": "^1.0.8", "@0xproject/utils": "^1.0.7", "@types/lodash": "4.14.104", - "@types/material-ui": "0.18.0", + "@types/material-ui": "^0.20.0", "@types/node": "^8.0.53", "@types/react": "*", "@types/react-dom": "*", @@ -45,7 +45,7 @@ "basscss": "^8.0.3", "compare-versions": "^3.0.1", "lodash": "^4.17.5", - "material-ui": "^0.17.1", + "material-ui": "^0.20.0", "react": "^16.4.2", "react-dom": "^16.4.2", "react-markdown": "^3.2.2", -- cgit v1.2.3 From 72710be04b1eae2a3d90bd8872501911f3bbad99 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:37:20 -0700 Subject: Remove react-tap-event-plugin from react-shared --- packages/react-shared/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 6b0a8d60a..10d89e6cd 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -49,8 +49,7 @@ "react-dom": "^16.4.2", "react-highlight": "0xproject/react-highlight#2f40a42e0a3f0ad126f9f42d505b97b603fc7162", "react-markdown": "^3.2.2", - "react-scroll": "0xproject/react-scroll#similar-to-pr-330", - "react-tap-event-plugin": "^2.0.1" + "react-scroll": "0xproject/react-scroll#similar-to-pr-330" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From 031807df9cb9258197bab671dda754e02b862267 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 15:52:09 -0700 Subject: Upgrade react-copy-to-clipboard --- packages/website/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/website/package.json b/packages/website/package.json index 50f9d18d1..1d148c080 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -43,7 +43,7 @@ "polished": "^1.9.2", "query-string": "^6.0.0", "react": "^16.4.2", - "react-copy-to-clipboard": "^4.2.3", + "react-copy-to-clipboard": "^5.0.0", "react-document-title": "^2.0.3", "react-dom": "^16.4.2", "react-helmet": "^5.2.0", -- cgit v1.2.3 From a18d0f62298de76a2c6cd503e457123221d6bf9a Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 17:49:15 -0700 Subject: Upgrade version of react-shared in website --- packages/react-shared/package.json | 2 +- packages/website/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 10d89e6cd..f341619d2 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -44,7 +44,7 @@ "change-case": "^3.0.2", "is-mobile": "^0.2.2", "lodash": "^4.17.5", - "material-ui": "0.20.0", + "material-ui": "^0.20.0", "react": "^16.4.2", "react-dom": "^16.4.2", "react-highlight": "0xproject/react-highlight#2f40a42e0a3f0ad126f9f42d505b97b603fc7162", diff --git a/packages/website/package.json b/packages/website/package.json index 1d148c080..3b6754fb3 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -21,7 +21,7 @@ "@0xproject/contract-wrappers": "^0.0.5", "@0xproject/order-utils": "^0.0.9", "@0xproject/react-docs": "^1.0.7", - "@0xproject/react-shared": "^1.0.7", + "@0xproject/react-shared": "^1.0.8", "@0xproject/subproviders": "^2.0.1", "@0xproject/types": "^0.8.1", "@0xproject/typescript-typings": "^0.4.3", -- cgit v1.2.3 From 68af0e9eb70151704098350f99437f92639de753 Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 28 Aug 2018 18:08:06 -0700 Subject: Change VersionDropDown to use material-ui 3 --- packages/react-shared/package.json | 1 + .../react-shared/src/components/version_drop_down.tsx | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'packages') diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index f341619d2..57aa9d51d 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -33,6 +33,7 @@ "typescript": "3.0.1" }, "dependencies": { + "@material-ui/core": "^3.0.1", "@types/is-mobile": "0.3.0", "@types/lodash": "4.14.104", "@types/material-ui": "0.18.0", diff --git a/packages/react-shared/src/components/version_drop_down.tsx b/packages/react-shared/src/components/version_drop_down.tsx index e41590957..e4a2798ab 100644 --- a/packages/react-shared/src/components/version_drop_down.tsx +++ b/packages/react-shared/src/components/version_drop_down.tsx @@ -1,6 +1,6 @@ +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; import * as _ from 'lodash'; -import DropDownMenu from 'material-ui/DropDownMenu'; -import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; export interface VersionDropDownProps { @@ -15,23 +15,22 @@ export class VersionDropDown extends React.Component - {this._renderDropDownItems()} - +
); } private _renderDropDownItems(): React.ReactNode[] { const items = _.map(this.props.versions, version => { - return ; + return v{version}; }); return items; } - private _updateSelectedVersion(_e: any, _index: number, semver: string): void { - this.props.onVersionSelected(semver); + private _updateSelectedVersion(event: React.ChangeEvent): void { + this.props.onVersionSelected(event.target.value); } } -- cgit v1.2.3 From 1c3b2b7141138f8da82197dfbdbdbfd76e7780b7 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 29 Aug 2018 11:39:52 -0700 Subject: Updated readBytes4 to match spec + added unit tests. These are 3.5/3.6 from audit --- .../protocol/AssetProxyOwner/AssetProxyOwner.sol | 13 +++++++++-- .../src/2.0.0/utils/LibBytes/LibBytes.sol | 7 +++++- packages/contracts/test/libraries/lib_bytes.ts | 26 +++++++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) (limited to 'packages') diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol index 8b7333646..e661f2427 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol @@ -105,11 +105,20 @@ contract AssetProxyOwner is uint256 index ) internal + pure returns (bytes4 result) { - require(b.length >= index + 4); + require( + b.length >= index + 4, + "GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED" + ); + + // Arrays are prefixed by a 32 byte length field + index += 32; + + // Read the bytes4 from array memory assembly { - result := mload(add(b, 32)) + result := mload(add(b, index)) // Solidity does not require us to clean the trailing bytes. // We do it anyway result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000) diff --git a/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol b/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol index 504e950a8..93873cbcc 100644 --- a/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol +++ b/packages/contracts/src/2.0.0/utils/LibBytes/LibBytes.sol @@ -467,8 +467,13 @@ library LibBytes { b.length >= index + 4, "GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED" ); + + // Arrays are prefixed by a 32 byte length field + index += 32; + + // Read the bytes4 from array memory assembly { - result := mload(add(b, 32)) + result := mload(add(b, index)) // Solidity does not require us to clean the trailing bytes. // We do it anyway result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000) diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 1c497a226..6fda9dc97 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -41,6 +41,8 @@ describe('LibBytes', () => { const testBytes32B = '0x534877abd8443578526845cdfef020047528759477fedef87346527659aced32'; const testUint256 = new BigNumber(testBytes32, 16); const testUint256B = new BigNumber(testBytes32B, 16); + const testBytes4 = '0xabcdef12'; + const testBytes4B = new BigNumber(testBytes4, 16); let shortData: string; let shortTestBytes: string; let shortTestBytesAsBuffer: Buffer; @@ -462,8 +464,9 @@ describe('LibBytes', () => { // AssertionError: expected promise to be rejected with an error including 'revert' but it was fulfilled with '0x08c379a0' it('should revert if byte array has a length < 4', async () => { const byteArrayLessThan4Bytes = '0x010101'; + const offset = new BigNumber(0); return expectContractCallFailed( - libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)), + libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo4LengthRequired, ); }); @@ -472,6 +475,27 @@ describe('LibBytes', () => { const expectedFirst4Bytes = byteArrayLongerThan32Bytes.slice(0, 10); expect(first4Bytes).to.equal(expectedFirst4Bytes); }); + it('should successfully read bytes4 when the bytes4 takes up the whole array', async () => { + const testBytes4Offset = new BigNumber(0); + const bytes4 = await libBytes.publicReadBytes4.callAsync(testBytes4, testBytes4Offset); + return expect(bytes4).to.be.equal(testBytes4); + }); + it('should successfully read bytes4 when it is offset in the array)', async () => { + const bytes4ByteArrayBuffer = ethUtil.toBuffer(testBytes4); + const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); + const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, bytes4ByteArrayBuffer]); + const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); + const testBytes4Offset = new BigNumber(prefixByteArrayBuffer.byteLength); + const bytes4 = await libBytes.publicReadBytes4.callAsync(combinedByteArray, testBytes4Offset); + return expect(bytes4).to.be.equal(testBytes4); + }); + it('should fail if the length between the offset and end of the byte array is too short to hold a bytes4', async () => { + const badOffset = new BigNumber(ethUtil.toBuffer(testBytes4).byteLength); + return expectContractCallFailed( + libBytes.publicReadBytes4.callAsync(testBytes4, badOffset), + RevertReason.LibBytesGreaterOrEqualTo4LengthRequired, + ); + }); }); describe('readBytesWithLength', () => { -- cgit v1.2.3 From 422e5e4dd734ce737bff42fb6a42ef07ad25f4b7 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 29 Aug 2018 11:57:52 -0700 Subject: Apply prettier --- packages/react-shared/src/components/version_drop_down.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'packages') diff --git a/packages/react-shared/src/components/version_drop_down.tsx b/packages/react-shared/src/components/version_drop_down.tsx index e4a2798ab..5ff4bed54 100644 --- a/packages/react-shared/src/components/version_drop_down.tsx +++ b/packages/react-shared/src/components/version_drop_down.tsx @@ -15,10 +15,7 @@ export class VersionDropDown extends React.Component - {this._renderDropDownItems()}
@@ -26,7 +23,11 @@ export class VersionDropDown extends React.Component { - return v{version}; + return ( + + v{version} + + ); }); return items; } -- cgit v1.2.3 From 8c803ab232d094c2f69d3b2d44cae11f153d2d5f Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 29 Aug 2018 12:25:06 -0700 Subject: Updated comments for ERC20 proxy to clarify how we load the token address from calldata (3.18 from audit) --- .../src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol | 67 +++++++++++++++++++--- .../src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol | 2 + 2 files changed, 60 insertions(+), 9 deletions(-) (limited to 'packages') diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol index 004c3892d..785f3aba9 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol @@ -59,15 +59,64 @@ contract ERC20Proxy is mstore(96, 0) revert(0, 100) } - - /////// Token contract address /////// - // The token address is found as follows: - // * It is stored at offset 4 in `assetData` contents. - // * This is stored at offset 32 from `assetData`. - // * The offset to `assetData` from Params is stored at offset - // 4 in calldata. - // * The offset of Params in calldata is 4. - // So we read location 4 and add 32 + 4 + 4 to it. + + // `transferFrom`. + // The function is marked `external`, so no abi decodeding is done for + // us. Instead, we expect the `calldata` memory to contain the + // following: + // + // | Area | Offset | Length | Contents | + // |----------|--------|---------|-------------------------------------| + // | Header | 0 | 4 | function selector | + // | Params | | 4 * 32 | function parameters: | + // | | 4 | | 1. offset to assetData (*) | + // | | 36 | | 2. from | + // | | 68 | | 3. to | + // | | 100 | | 4. amount | + // | Data | | | assetData: | + // | | 132 | 32 | assetData Length | + // | | 164 | ** | assetData Contents | + // + // (*): offset is computed from start of function parameters, so offset + // by an additional 4 bytes in the calldata. + // + // (**): see table below to compute length of assetData Contents + // + // WARNING: The ABIv2 specification allows additional padding between + // the Params and Data section. This will result in a larger + // offset to assetData. + + // Asset data itself is encoded as follows: + // + // | Area | Offset | Length | Contents | + // |----------|--------|---------|-------------------------------------| + // | Header | 0 | 4 | function selector | + // | Params | | 1 * 32 | function parameters: | + // | | 4 | 12 + 20 | 1. token address | + + // We construct calldata for the `token.transferFrom` ABI. + // The layout of this calldata is in the table below. + // + // | Area | Offset | Length | Contents | + // |----------|--------|---------|-------------------------------------| + // | Header | 0 | 4 | function selector | + // | Params | | 3 * 32 | function parameters: | + // | | 4 | | 1. from | + // | | 36 | | 2. to | + // | | 68 | | 3. amount | + + /////// Read token address from calldata /////// + // * The token address is stored in `assetData`. + // + // * The "offset to assetData" is stored at offset 4 in the calldata (table 1). + // [assetDataOffsetFromParams = calldataload(4)] + // + // * Notes that the "offset to assetData" is relative to the "Params" area of calldata; + // add 4 bytes to account for the length of the "Header" area (table 1). + // [assetDataOffsetFromHeader = assetDataOffsetFromParams + 4] + // + // * The "token address" is offset 32+4=36 bytes into "assetData" (tables 1 & 2). + // [tokenOffset = assetDataOffsetFromHeader + 36 = calldataload(4) + 4 + 36] let token := calldataload(add(calldataload(4), 40)) /////// Setup Header Area /////// diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol index 9d0bc0f74..caf05b0dd 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol @@ -80,6 +80,8 @@ contract ERC721Proxy is // (*): offset is computed from start of function parameters, so offset // by an additional 4 bytes in the calldata. // + // (**): see table below to compute length of assetData Contents + // // WARNING: The ABIv2 specification allows additional padding between // the Params and Data section. This will result in a larger // offset to assetData. -- cgit v1.2.3 From 62b93cf2ebf242ea5b432daddc030b24da46421f Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 29 Aug 2018 13:14:51 -0700 Subject: More tests for LibBytes --- packages/contracts/test/libraries/lib_bytes.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 6fda9dc97..646875f1e 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -42,7 +42,7 @@ describe('LibBytes', () => { const testUint256 = new BigNumber(testBytes32, 16); const testUint256B = new BigNumber(testBytes32B, 16); const testBytes4 = '0xabcdef12'; - const testBytes4B = new BigNumber(testBytes4, 16); + const testByte = '0xab'; let shortData: string; let shortTestBytes: string; let shortTestBytesAsBuffer: Buffer; @@ -108,13 +108,19 @@ describe('LibBytes', () => { RevertReason.LibBytesGreaterThanZeroLengthRequired, ); }); - it('should pop the last byte from the input and return it', async () => { + it('should pop the last byte from the input and return it when array holds more than 1 byte', async () => { const [newBytes, poppedByte] = await libBytes.publicPopLastByte.callAsync(byteArrayLongerThan32Bytes); const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -2); const expectedPoppedByte = `0x${byteArrayLongerThan32Bytes.slice(-2)}`; expect(newBytes).to.equal(expectedNewBytes); expect(poppedByte).to.equal(expectedPoppedByte); }); + it('should pop the last byte from the input and return it when array is exactly one', async () => { + const [newBytes, poppedByte] = await libBytes.publicPopLastByte.callAsync(testByte); + const expectedNewBytes = '0x'; + expect(newBytes).to.equal(expectedNewBytes); + return expect(poppedByte).to.be.equal(testByte); + }); }); describe('popLast20Bytes', () => { @@ -124,13 +130,20 @@ describe('LibBytes', () => { RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); }); - it('should pop the last 20 bytes from the input and return it', async () => { + it('should pop the last 20 bytes from the input and return it when array holds more than one byte', async () => { const [newBytes, poppedAddress] = await libBytes.publicPopLast20Bytes.callAsync(byteArrayLongerThan32Bytes); const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -40); const expectedPoppedAddress = `0x${byteArrayLongerThan32Bytes.slice(-40)}`; expect(newBytes).to.equal(expectedNewBytes); expect(poppedAddress).to.equal(expectedPoppedAddress); }); + it('should pop the last 20 bytes from the input and return it when array is exactly 20 bytes', async () => { + const [newBytes, poppedAddress] = await libBytes.publicPopLast20Bytes.callAsync(testAddress); + const expectedNewBytes = '0x'; + const expectedPoppedAddress = testAddress; + expect(newBytes).to.equal(expectedNewBytes); + expect(poppedAddress).to.equal(expectedPoppedAddress); + }); }); describe('equals', () => { -- cgit v1.2.3 From 5f1c9cfee503bd3fb53fe12bb21f42f3f7981dc7 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 29 Aug 2018 13:15:40 -0700 Subject: Reverted syntax used by readBytes4 in AssetProxyOwner to be compatible with Solidity v0.4.10 --- .../src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'packages') diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol index e661f2427..7da3d87e2 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol @@ -105,13 +105,9 @@ contract AssetProxyOwner is uint256 index ) internal - pure returns (bytes4 result) { - require( - b.length >= index + 4, - "GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED" - ); + require(b.length >= index + 4); // Arrays are prefixed by a 32 byte length field index += 32; -- cgit v1.2.3 From aa833ef074b5492dec876b2991175cbd9eae599c Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 29 Aug 2018 13:17:13 -0700 Subject: Typos in LibBytes tests --- packages/contracts/test/libraries/lib_bytes.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 646875f1e..efdfa13a2 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -115,7 +115,7 @@ describe('LibBytes', () => { expect(newBytes).to.equal(expectedNewBytes); expect(poppedByte).to.equal(expectedPoppedByte); }); - it('should pop the last byte from the input and return it when array is exactly one', async () => { + it('should pop the last byte from the input and return it when array is exactly 1 byte', async () => { const [newBytes, poppedByte] = await libBytes.publicPopLastByte.callAsync(testByte); const expectedNewBytes = '0x'; expect(newBytes).to.equal(expectedNewBytes); @@ -130,7 +130,7 @@ describe('LibBytes', () => { RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); }); - it('should pop the last 20 bytes from the input and return it when array holds more than one byte', async () => { + it('should pop the last 20 bytes from the input and return it when array holds more than 20 bytes', async () => { const [newBytes, poppedAddress] = await libBytes.publicPopLast20Bytes.callAsync(byteArrayLongerThan32Bytes); const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -40); const expectedPoppedAddress = `0x${byteArrayLongerThan32Bytes.slice(-40)}`; @@ -318,7 +318,7 @@ describe('LibBytes', () => { const bytes32 = await libBytes.publicReadBytes32.callAsync(testBytes32, testBytes32Offset); return expect(bytes32).to.be.equal(testBytes32); }); - it('should successfully read bytes32 when it is offset in the array)', async () => { + it('should successfully read bytes32 when it is offset in the array', async () => { const bytes32ByteArrayBuffer = ethUtil.toBuffer(testBytes32); const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, bytes32ByteArrayBuffer]); @@ -493,7 +493,7 @@ describe('LibBytes', () => { const bytes4 = await libBytes.publicReadBytes4.callAsync(testBytes4, testBytes4Offset); return expect(bytes4).to.be.equal(testBytes4); }); - it('should successfully read bytes4 when it is offset in the array)', async () => { + it('should successfully read bytes4 when it is offset in the array', async () => { const bytes4ByteArrayBuffer = ethUtil.toBuffer(testBytes4); const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, bytes4ByteArrayBuffer]); @@ -583,7 +583,7 @@ describe('LibBytes', () => { }); describe('writeBytesWithLength', () => { - it('should successfully write short, nested array of bytes when it takes up the whole array)', async () => { + it('should successfully write short, nested array of bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( @@ -692,7 +692,7 @@ describe('LibBytes', () => { RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); }); - it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array)', async () => { + it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => { const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength); return expectContractCallFailed( -- cgit v1.2.3 From dcb12b6ad6485f987d574ee3b20bf24aaf7a7d40 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Wed, 29 Aug 2018 14:05:28 -0700 Subject: Update AssetProxyOwner to 0.4.24 --- .../protocol/AssetProxyOwner/AssetProxyOwner.sol | 49 +++++++--------------- .../TestAssetProxyOwner/TestAssetProxyOwner.sol | 23 +++------- .../contracts/test/multisig/asset_proxy_owner.ts | 19 --------- 3 files changed, 21 insertions(+), 70 deletions(-) (limited to 'packages') diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol index 7da3d87e2..bb02d8489 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol @@ -16,15 +16,18 @@ */ -pragma solidity 0.4.10; +pragma solidity 0.4.24; import "../../multisig/MultiSigWalletWithTimeLock.sol"; +import "../../utils/LibBytes/LibBytes.sol"; contract AssetProxyOwner is MultiSigWalletWithTimeLock { + using LibBytes for bytes; + event AssetProxyRegistration(address assetProxyContract, bool isRegistered); // Mapping of AssetProxy contract address => @@ -37,8 +40,14 @@ contract AssetProxyOwner is /// on an approved AssetProxy contract. modifier validRemoveAuthorizedAddressAtIndexTx(uint256 transactionId) { Transaction storage tx = transactions[transactionId]; - require(isAssetProxyRegistered[tx.destination]); - require(readBytes4(tx.data, 0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR); + require( + isAssetProxyRegistered[tx.destination], + "UNREGISTERED_ASSET_PROXY" + ); + require( + tx.data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR, + "INVALID_FUNCTION_SELECTOR" + ); _; } @@ -48,7 +57,7 @@ contract AssetProxyOwner is /// @param _assetProxyContracts Array of AssetProxy contract addresses. /// @param _required Number of required confirmations. /// @param _secondsTimeLocked Duration needed after a transaction is confirmed and before it becomes executable, in seconds. - function AssetProxyOwner( + constructor ( address[] memory _owners, address[] memory _assetProxyContracts, uint256 _required, @@ -74,7 +83,7 @@ contract AssetProxyOwner is notNull(assetProxyContract) { isAssetProxyRegistered[assetProxyContract] = isRegistered; - AssetProxyRegistration(assetProxyContract, isRegistered); + emit AssetProxyRegistration(assetProxyContract, isRegistered); } /// @dev Allows execution of `removeAuthorizedAddressAtIndex` without time lock. @@ -89,36 +98,10 @@ contract AssetProxyOwner is tx.executed = true; // solhint-disable-next-line avoid-call-value if (tx.destination.call.value(tx.value)(tx.data)) - Execution(transactionId); + emit Execution(transactionId); else { - ExecutionFailure(transactionId); + emit ExecutionFailure(transactionId); tx.executed = false; } } - - /// @dev Reads an unpadded bytes4 value from a position in a byte array. - /// @param b Byte array containing a bytes4 value. - /// @param index Index in byte array of bytes4 value. - /// @return bytes4 value from byte array. - function readBytes4( - bytes memory b, - uint256 index - ) - internal - returns (bytes4 result) - { - require(b.length >= index + 4); - - // Arrays are prefixed by a 32 byte length field - index += 32; - - // Read the bytes4 from array memory - assembly { - result := mload(add(b, index)) - // Solidity does not require us to clean the trailing bytes. - // We do it anyway - result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000) - } - return result; - } } diff --git a/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol b/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol index 75e782d43..38ec42a72 100644 --- a/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/test/TestAssetProxyOwner/TestAssetProxyOwner.sol @@ -16,7 +16,7 @@ */ -pragma solidity 0.4.10; +pragma solidity 0.4.24; import "../../protocol/AssetProxyOwner/AssetProxyOwner.sol"; @@ -26,7 +26,7 @@ contract TestAssetProxyOwner is AssetProxyOwner { - function TestAssetProxyOwner( + constructor ( address[] memory _owners, address[] memory _assetProxyContracts, uint256 _required, @@ -38,6 +38,7 @@ contract TestAssetProxyOwner is function testValidRemoveAuthorizedAddressAtIndexTx(uint256 id) public + view validRemoveAuthorizedAddressAtIndexTx(id) returns (bool) { @@ -50,23 +51,9 @@ contract TestAssetProxyOwner is /// @return Successful if data is a call to `removeAuthorizedAddressAtIndex`. function isFunctionRemoveAuthorizedAddressAtIndex(bytes memory data) public + pure returns (bool) { - return readBytes4(data, 0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR; - } - - /// @dev Reads an unpadded bytes4 value from a position in a byte array. - /// @param b Byte array containing a bytes4 value. - /// @param index Index in byte array of bytes4 value. - /// @return bytes4 value from byte array. - function publicReadBytes4( - bytes memory b, - uint256 index - ) - public - returns (bytes4 result) - { - result = readBytes4(b, index); - return result; + return data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR; } } diff --git a/packages/contracts/test/multisig/asset_proxy_owner.ts b/packages/contracts/test/multisig/asset_proxy_owner.ts index 9515941ff..2f626daef 100644 --- a/packages/contracts/test/multisig/asset_proxy_owner.ts +++ b/packages/contracts/test/multisig/asset_proxy_owner.ts @@ -148,25 +148,6 @@ describe('AssetProxyOwner', () => { }); }); - describe('readBytes4', () => { - it('should revert if byte array has a length < 4', async () => { - const byteArrayLessThan4Bytes = '0x010101'; - return expectContractCallFailedWithoutReasonAsync( - testAssetProxyOwner.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)), - ); - }); - it('should return the first 4 bytes of a byte array of arbitrary length', async () => { - const byteArrayLongerThan32Bytes = - '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const first4Bytes = await testAssetProxyOwner.publicReadBytes4.callAsync( - byteArrayLongerThan32Bytes, - new BigNumber(0), - ); - const expectedFirst4Bytes = byteArrayLongerThan32Bytes.slice(0, 10); - expect(first4Bytes).to.equal(expectedFirst4Bytes); - }); - }); - describe('registerAssetProxy', () => { it('should throw if not called by multisig', async () => { const isRegistered = true; -- cgit v1.2.3 From bf3ab1127d11a7530c1abe8236e149d3d96fd35b Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Wed, 29 Aug 2018 14:42:42 -0700 Subject: Remove unused imports --- packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol | 1 - packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol | 1 - .../src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) (limited to 'packages') diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol index 785f3aba9..258443bca 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC20Proxy.sol @@ -18,7 +18,6 @@ pragma solidity 0.4.24; -import "../../utils/LibBytes/LibBytes.sol"; import "./MixinAuthorizable.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol index caf05b0dd..65b664b8b 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol @@ -18,7 +18,6 @@ pragma solidity 0.4.24; -import "../../utils/LibBytes/LibBytes.sol"; import "./MixinAuthorizable.sol"; diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol index 80475e6e3..e90b62f19 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinAssetProxyDispatcher.sol @@ -19,7 +19,6 @@ pragma solidity 0.4.24; import "../../utils/Ownable/Ownable.sol"; -import "../../utils/LibBytes/LibBytes.sol"; import "./mixins/MAssetProxyDispatcher.sol"; import "../AssetProxy/interfaces/IAssetProxy.sol"; @@ -28,7 +27,6 @@ contract MixinAssetProxyDispatcher is Ownable, MAssetProxyDispatcher { - using LibBytes for bytes; // Mapping from Asset Proxy Id's to their respective Asset Proxy mapping (bytes4 => IAssetProxy) public assetProxies; @@ -90,7 +88,7 @@ contract MixinAssetProxyDispatcher is "LENGTH_GREATER_THAN_3_REQUIRED" ); - // Lookup assetProxy + // Lookup assetProxy. We do not use `LibBytes.readBytes4` for gas efficiency reasons. bytes4 assetProxyId; assembly { assetProxyId := and(mload( -- cgit v1.2.3 From d80701c2779512324c7a9bef2a87b6f63239d281 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Wed, 29 Aug 2018 15:35:09 -0700 Subject: Fix geth tests --- .../protocol/AssetProxyOwner/AssetProxyOwner.sol | 5 ++- .../contracts/test/exchange/signature_validator.ts | 14 +++---- packages/contracts/test/libraries/lib_bytes.ts | 48 +++++++++++----------- .../contracts/test/multisig/asset_proxy_owner.ts | 26 ++++++++---- .../test/tokens/unlimited_allowance_token.ts | 8 ++-- packages/contracts/test/utils/assertions.ts | 17 +++++++- packages/types/CHANGELOG.json | 9 ++++ packages/types/src/index.ts | 3 ++ 8 files changed, 83 insertions(+), 47 deletions(-) (limited to 'packages') diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol index bb02d8489..4d00e92d3 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxyOwner/AssetProxyOwner.sol @@ -68,7 +68,10 @@ contract AssetProxyOwner is { for (uint256 i = 0; i < _assetProxyContracts.length; i++) { address assetProxy = _assetProxyContracts[i]; - require(assetProxy != address(0)); + require( + assetProxy != address(0), + "INVALID_ASSET_PROXY" + ); isAssetProxyRegistered[assetProxy] = true; } } diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index da2febfd8..b25483c4b 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -14,7 +14,7 @@ import { ValidatorContract } from '../../generated_contract_wrappers/validator'; import { WalletContract } from '../../generated_contract_wrappers/wallet'; import { addressUtils } from '../utils/address_utils'; import { artifacts } from '../utils/artifacts'; -import { expectContractCallFailed, expectContractCallFailedWithoutReasonAsync } from '../utils/assertions'; +import { expectContractCallFailedAsync, expectContractCallFailedWithoutReasonAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { LogDecoder } from '../utils/log_decoder'; @@ -119,7 +119,7 @@ describe('MixinSignatureValidator', () => { it('should revert when signature is empty', async () => { const emptySignature = '0x'; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectContractCallFailed( + return expectContractCallFailedAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -133,7 +133,7 @@ describe('MixinSignatureValidator', () => { const unsupportedSignatureType = SignatureType.NSignatureTypes; const unsupportedSignatureHex = '0x' + Buffer.from([unsupportedSignatureType]).toString('hex'); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectContractCallFailed( + return expectContractCallFailedAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -146,7 +146,7 @@ describe('MixinSignatureValidator', () => { it('should revert when SignatureType=Illegal', async () => { const unsupportedSignatureHex = '0x' + Buffer.from([SignatureType.Illegal]).toString('hex'); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectContractCallFailed( + return expectContractCallFailedAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -173,7 +173,7 @@ describe('MixinSignatureValidator', () => { const signatureBuffer = Buffer.concat([fillerData, signatureType]); const signatureHex = ethUtil.bufferToHex(signatureBuffer); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectContractCallFailed( + return expectContractCallFailedAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, @@ -339,7 +339,7 @@ describe('MixinSignatureValidator', () => { ethUtil.toBuffer(`0x${SignatureType.Wallet}`), ]); const signatureHex = ethUtil.bufferToHex(signature); - await expectContractCallFailed( + await expectContractCallFailedAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, maliciousWallet.address, @@ -385,7 +385,7 @@ describe('MixinSignatureValidator', () => { const signature = Buffer.concat([validatorAddress, signatureType]); const signatureHex = ethUtil.bufferToHex(signature); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - await expectContractCallFailed( + await expectContractCallFailedAsync( signatureValidator.publicIsValidSignature.callAsync(orderHashHex, signerAddress, signatureHex), RevertReason.ValidatorError, ); diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index efdfa13a2..13640a761 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -9,7 +9,7 @@ import * as _ from 'lodash'; import { TestLibBytesContract } from '../../generated_contract_wrappers/test_lib_bytes'; import { artifacts } from '../utils/artifacts'; -import { expectContractCallFailed } from '../utils/assertions'; +import { expectContractCallFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { typeEncodingUtils } from '../utils/type_encoding_utils'; @@ -103,7 +103,7 @@ describe('LibBytes', () => { describe('popLastByte', () => { it('should revert if length is 0', async () => { - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicPopLastByte.callAsync(constants.NULL_BYTES), RevertReason.LibBytesGreaterThanZeroLengthRequired, ); @@ -125,7 +125,7 @@ describe('LibBytes', () => { describe('popLast20Bytes', () => { it('should revert if length is less than 20', async () => { - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicPopLast20Bytes.callAsync(byteArrayShorterThan20Bytes), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -200,7 +200,7 @@ describe('LibBytes', () => { describe('deepCopyBytes', () => { it('should revert if dest is shorter than source', async () => { - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicDeepCopyBytes.callAsync(byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes), RevertReason.LibBytesGreaterOrEqualToSourceBytesLengthRequired, ); @@ -253,7 +253,7 @@ describe('LibBytes', () => { it('should fail if the byte array is too short to hold an address', async () => { const shortByteArray = '0xabcdef'; const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadAddress.callAsync(shortByteArray, offset), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -261,7 +261,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => { const byteArray = testAddress; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadAddress.callAsync(byteArray, badOffset), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -297,7 +297,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold an address', async () => { const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteAddress.callAsync(byteArrayShorterThan20Bytes, offset, testAddress), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -305,7 +305,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => { const byteArray = byteArrayLongerThan32Bytes; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteAddress.callAsync(byteArray, badOffset, testAddress), RevertReason.LibBytesGreaterOrEqualTo20LengthRequired, ); @@ -329,14 +329,14 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a bytes32', async () => { const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytes32.callAsync(byteArrayShorterThan32Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytes32.callAsync(testBytes32, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -372,7 +372,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a bytes32', async () => { const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteBytes32.callAsync(byteArrayShorterThan32Bytes, offset, testBytes32), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -380,7 +380,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => { const byteArray = byteArrayLongerThan32Bytes; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteBytes32.callAsync(byteArray, badOffset, testBytes32), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -408,7 +408,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a uint256', async () => { const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadUint256.callAsync(byteArrayShorterThan32Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -418,7 +418,7 @@ describe('LibBytes', () => { const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256); const byteArray = ethUtil.bufferToHex(testUint256AsBuffer); const badOffset = new BigNumber(testUint256AsBuffer.byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadUint256.callAsync(byteArray, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -458,7 +458,7 @@ describe('LibBytes', () => { }); it('should fail if the byte array is too short to hold a uint256', async () => { const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteUint256.callAsync(byteArrayShorterThan32Bytes, offset, testUint256), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -466,7 +466,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => { const byteArray = byteArrayLongerThan32Bytes; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteUint256.callAsync(byteArray, badOffset, testUint256), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -478,7 +478,7 @@ describe('LibBytes', () => { it('should revert if byte array has a length < 4', async () => { const byteArrayLessThan4Bytes = '0x010101'; const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo4LengthRequired, ); @@ -504,7 +504,7 @@ describe('LibBytes', () => { }); it('should fail if the length between the offset and end of the byte array is too short to hold a bytes4', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes4).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytes4.callAsync(testBytes4, badOffset), RevertReason.LibBytesGreaterOrEqualTo4LengthRequired, ); @@ -554,28 +554,28 @@ describe('LibBytes', () => { it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { // The length of the nested array is 32 bytes. By storing less than 32 bytes, a length cannot be read. const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, offset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); }); it('should fail if we store a nested byte array length, without a nested byte array', async () => { const offset = new BigNumber(0); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytesWithLength.callAsync(testBytes32, offset), RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicReadBytesWithLength.callAsync(testBytes32, badOffset), RevertReason.LibBytesGreaterOrEqualTo32LengthRequired, ); @@ -687,7 +687,7 @@ describe('LibBytes', () => { it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { const offset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(1)); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, offset, longData), RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); @@ -695,7 +695,7 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => { const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength); - return expectContractCallFailed( + return expectContractCallFailedAsync( libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, badOffset, shortData), RevertReason.LibBytesGreaterOrEqualToNestedBytesLengthRequired, ); diff --git a/packages/contracts/test/multisig/asset_proxy_owner.ts b/packages/contracts/test/multisig/asset_proxy_owner.ts index 2f626daef..bb2b3b1a3 100644 --- a/packages/contracts/test/multisig/asset_proxy_owner.ts +++ b/packages/contracts/test/multisig/asset_proxy_owner.ts @@ -1,4 +1,5 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { RevertReason } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; @@ -14,9 +15,11 @@ import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mix import { TestAssetProxyOwnerContract } from '../../generated_contract_wrappers/test_asset_proxy_owner'; import { artifacts } from '../utils/artifacts'; import { - expectContractCallFailedWithoutReasonAsync, - expectContractCreationFailedWithoutReason, + expectContractCallFailedAsync, + expectContractCreationFailedAsync, + expectTransactionFailedAsync, expectTransactionFailedWithoutReasonAsync, + sendTransactionResult, } from '../utils/assertions'; import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp'; import { chaiSetup } from '../utils/chai_setup'; @@ -109,8 +112,8 @@ describe('AssetProxyOwner', () => { }); it('should throw if a null address is included in assetProxyContracts', async () => { const assetProxyContractAddresses = [erc20Proxy.address, constants.NULL_ADDRESS]; - return expectContractCreationFailedWithoutReason( - AssetProxyOwnerContract.deployFrom0xArtifactAsync( + return expectContractCreationFailedAsync( + (AssetProxyOwnerContract.deployFrom0xArtifactAsync( artifacts.AssetProxyOwner, provider, txDefaults, @@ -118,7 +121,8 @@ describe('AssetProxyOwner', () => { assetProxyContractAddresses, REQUIRED_APPROVALS, SECONDS_TIME_LOCKED, - ), + ) as any) as sendTransactionResult, + RevertReason.InvalidAssetProxy, ); }); }); @@ -281,8 +285,9 @@ describe('AssetProxyOwner', () => { ); const log = submitTxRes.logs[0] as LogWithDecodedArgs; const txId = log.args.transactionId; - return expectContractCallFailedWithoutReasonAsync( + return expectContractCallFailedAsync( testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), + RevertReason.InvalidFunctionSelector, ); }); @@ -316,8 +321,9 @@ describe('AssetProxyOwner', () => { ); const log = submitTxRes.logs[0] as LogWithDecodedArgs; const txId = log.args.transactionId; - return expectContractCallFailedWithoutReasonAsync( + return expectContractCallFailedAsync( testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), + RevertReason.UnregisteredAssetProxy, ); }); }); @@ -358,10 +364,11 @@ describe('AssetProxyOwner', () => { await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - return expectTransactionFailedWithoutReasonAsync( + return expectTransactionFailedAsync( testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { from: owners[1], }), + RevertReason.UnregisteredAssetProxy, ); }); @@ -380,10 +387,11 @@ describe('AssetProxyOwner', () => { await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - return expectTransactionFailedWithoutReasonAsync( + return expectTransactionFailedAsync( testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { from: owners[1], }), + RevertReason.InvalidFunctionSelector, ); }); diff --git a/packages/contracts/test/tokens/unlimited_allowance_token.ts b/packages/contracts/test/tokens/unlimited_allowance_token.ts index f2725b408..63680fe9b 100644 --- a/packages/contracts/test/tokens/unlimited_allowance_token.ts +++ b/packages/contracts/test/tokens/unlimited_allowance_token.ts @@ -5,7 +5,7 @@ import * as chai from 'chai'; import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; import { artifacts } from '../utils/artifacts'; -import { expectContractCallFailed } from '../utils/assertions'; +import { expectContractCallFailedAsync } from '../utils/assertions'; import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; @@ -54,7 +54,7 @@ describe('UnlimitedAllowanceToken', () => { it('should throw if owner has insufficient balance', async () => { const ownerBalance = await token.balanceOf.callAsync(owner); const amountToTransfer = ownerBalance.plus(1); - return expectContractCallFailed( + return expectContractCallFailedAsync( token.transfer.callAsync(spender, amountToTransfer, { from: owner }), RevertReason.Erc20InsufficientBalance, ); @@ -93,7 +93,7 @@ describe('UnlimitedAllowanceToken', () => { await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); - return expectContractCallFailed( + return expectContractCallFailedAsync( token.transferFrom.callAsync(owner, spender, amountToTransfer, { from: spender, }), @@ -109,7 +109,7 @@ describe('UnlimitedAllowanceToken', () => { const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0; expect(isSpenderAllowanceInsufficient).to.be.true(); - return expectContractCallFailed( + return expectContractCallFailedAsync( token.transferFrom.callAsync(owner, spender, amountToTransfer, { from: spender, }), diff --git a/packages/contracts/test/utils/assertions.ts b/packages/contracts/test/utils/assertions.ts index 61df800c8..3361a751a 100644 --- a/packages/contracts/test/utils/assertions.ts +++ b/packages/contracts/test/utils/assertions.ts @@ -159,7 +159,7 @@ export async function expectTransactionFailedWithoutReasonAsync(p: sendTransacti * @returns a new Promise which will reject if the conditions are not met and * otherwise resolve with no value. */ -export async function expectContractCallFailed(p: Promise, reason: RevertReason): Promise { +export async function expectContractCallFailedAsync(p: Promise, reason: RevertReason): Promise { return expect(p).to.be.rejectedWith(reason); } @@ -180,7 +180,20 @@ export async function expectContractCallFailedWithoutReasonAsync(p: Promise(p: Promise): Promise { +export async function expectContractCreationFailedAsync( + p: sendTransactionResult, + reason: RevertReason, +): Promise { + return expectTransactionFailedAsync(p, reason); +} + +/** + * Resolves if the contract creation/deployment fails without a revert reason. + * @param p a Promise resulting from a contract creation/deployment + * @returns a new Promise which will reject if the conditions are not met and + * otherwise resolve with no value. + */ +export async function expectContractCreationFailedWithoutReasonAsync(p: Promise): Promise { const errMessage = await _getTransactionFailedErrorMessageAsync(); return expect(p).to.be.rejectedWith(errMessage); } diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index e96d2a742..0bd9e3b37 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "1.0.1-rc.7", + "changes": [ + { + "note": "Add AssetProxyOwner revert reasons", + "pr": 1041 + } + ] + }, { "version": "1.0.1-rc.6", "changes": [ diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index d8bffccf9..3011dd87f 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -224,6 +224,9 @@ export enum RevertReason { Erc721InvalidSelector = 'ERC721_INVALID_SELECTOR', WalletError = 'WALLET_ERROR', ValidatorError = 'VALIDATOR_ERROR', + InvalidFunctionSelector = 'INVALID_FUNCTION_SELECTOR', + InvalidAssetProxy = 'INVALID_ASSET_PROXY', + UnregisteredAssetProxy = 'UNREGISTERED_ASSET_PROXY', } export enum StatusCodes { -- cgit v1.2.3