aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-06-25 17:45:17 +0800
committerFabio Berger <me@fabioberger.com>2018-06-25 17:45:17 +0800
commitdf79fb19aff1aa1ed7b1346feccfa3d235c25ea0 (patch)
treed19445672189e3e7a9927dde7ebaa4734493139d /packages/contracts/src
parent2f6f815d81ff0f36a35a31c40bff7df1a974a1af (diff)
parentf8bde5ab9b8e5d4ec8b9532dfbf18d1202dbfb29 (diff)
downloaddexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.tar
dexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.tar.gz
dexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.tar.bz2
dexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.tar.lz
dexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.tar.xz
dexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.tar.zst
dexon-sol-tools-df79fb19aff1aa1ed7b1346feccfa3d235c25ea0.zip
Merge branch 'v2-prototype' into refactor/check-revert-reasons
* v2-prototype: (48 commits) Fix typos in comments Add modifier and tests for removeAuthorizedAddressAtIndex Update and add tests Change removeAuthorizedAddress => removeAuthorizedAddressAtIndex Move isFunctionRemoveAuthorizedAddress to test Fix usage of `popLastByte` Fix LibBytes is a library Remove `areBytesEqual` Fix usage of `contentAddress()` Clean low bits in bytes4 Clean high bits in address Refactor LibBytes.readBytes4 for consistency Fix LibBytes.equals Add trailing garbage testcase for LibBytes.equals Rename bytes.equals Add slice and sliceDestructive Rename bytes.rawAddress and add bytes.contentAddress Rename read/writeBytesWithLength Using LibBytes for bytes Make LibBytes a library ... # Conflicts: # packages/contracts/src/contracts/current/utils/Ownable/Ownable.sol # packages/contracts/test/libraries/lib_bytes.ts
Diffstat (limited to 'packages/contracts/src')
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/MixinAuthorizable.sol7
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol5
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol9
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxyOwner/AssetProxyOwner.sol33
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinAssetProxyDispatcher.sol2
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol7
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol6
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol21
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol26
-rw-r--r--packages/contracts/src/contracts/current/test/TestAssetProxyOwner/TestAssetProxyOwner.sol56
-rw-r--r--packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol91
-rw-r--r--packages/contracts/src/contracts/current/test/TestLibMem/TestLibMem.sol56
-rw-r--r--packages/contracts/src/contracts/current/test/TestWallet/TestWallet.sol8
-rw-r--r--packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol279
-rw-r--r--packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol142
-rw-r--r--packages/contracts/src/contracts/current/utils/Ownable/Ownable.sol5
-rw-r--r--packages/contracts/src/utils/artifacts.ts4
-rw-r--r--packages/contracts/src/utils/multi_sig_wrapper.ts6
-rw-r--r--packages/contracts/src/utils/types.ts1
19 files changed, 424 insertions, 340 deletions
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinAuthorizable.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinAuthorizable.sol
index 8cb4254c5..37c12f861 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinAuthorizable.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinAuthorizable.sol
@@ -69,7 +69,7 @@ contract MixinAuthorizable is
);
delete authorized[target];
- for (uint i = 0; i < authorities.length; i++) {
+ for (uint256 i = 0; i < authorities.length; i++) {
if (authorities[i] == target) {
authorities[i] = authorities[authorities.length - 1];
authorities.length -= 1;
@@ -87,8 +87,13 @@ contract MixinAuthorizable is
uint256 index
)
external
+ onlyOwner
{
require(
+ authorized[target],
+ TARGET_NOT_AUTHORIZED
+ );
+ require(
index < authorities.length,
INDEX_OUT_OF_BOUNDS
);
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol
index 4af39a00b..0e7f3fc89 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol
@@ -24,9 +24,10 @@ import "../../tokens/ERC20Token/IERC20Token.sol";
import "./libs/LibTransferErrors.sol";
contract MixinERC20Transfer is
- LibBytes,
LibTransferErrors
{
+ using LibBytes for bytes;
+
/// @dev Internal version of `transferFrom`.
/// @param assetData Encoded byte array.
/// @param from Address to transfer asset from.
@@ -41,7 +42,7 @@ contract MixinERC20Transfer is
internal
{
// Decode asset data.
- address token = readAddress(assetData, 0);
+ address token = assetData.readAddress(0);
// Transfer tokens.
// We do a raw call so we can check the success separate
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol
index 6e3156e8a..944068bbb 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol
@@ -24,9 +24,10 @@ import "../../tokens/ERC721Token/ERC721Token.sol";
import "./libs/LibTransferErrors.sol";
contract MixinERC721Transfer is
- LibBytes,
LibTransferErrors
{
+ using LibBytes for bytes;
+
/// @dev Internal version of `transferFrom`.
/// @param assetData Encoded byte array.
/// @param from Address to transfer asset from.
@@ -78,10 +79,10 @@ contract MixinERC721Transfer is
)
{
// Decode asset data.
- token = readAddress(assetData, 0);
- tokenId = readUint256(assetData, 20);
+ token = assetData.readAddress(0);
+ tokenId = assetData.readUint256(20);
if (assetData.length > 52) {
- receiverData = readBytes(assetData, 52);
+ receiverData = assetData.readBytesWithLength(52);
}
return (
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxyOwner/AssetProxyOwner.sol b/packages/contracts/src/contracts/current/protocol/AssetProxyOwner/AssetProxyOwner.sol
index 7f5f056b5..eb58b3374 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxyOwner/AssetProxyOwner.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxyOwner/AssetProxyOwner.sol
@@ -22,24 +22,24 @@ import "../../multisig/MultiSigWalletWithTimeLock.sol";
import "../../utils/LibBytes/LibBytes.sol";
contract AssetProxyOwner is
- LibBytes,
MultiSigWalletWithTimeLock
{
+ using LibBytes for bytes;
event AssetProxyRegistration(address assetProxyContract, bool isRegistered);
// Mapping of AssetProxy contract address =>
- // if this contract is allowed to call the AssetProxy's removeAuthorizedAddress method without a time lock.
+ // if this contract is allowed to call the AssetProxy's `removeAuthorizedAddressAtIndex` method without a time lock.
mapping (address => bool) public isAssetProxyRegistered;
- bytes4 constant REMOVE_AUTHORIZED_ADDRESS_SELECTOR = bytes4(keccak256("removeAuthorizedAddress(address)"));
+ bytes4 constant REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR = bytes4(keccak256("removeAuthorizedAddressAtIndex(address,uint256)"));
- /// @dev Function will revert if the transaction does not call `removeAuthorizedAddress`
+ /// @dev Function will revert if the transaction does not call `removeAuthorizedAddressAtIndex`
/// on an approved AssetProxy contract.
- modifier validRemoveAuthorizedAddressTx(uint256 transactionId) {
+ modifier validRemoveAuthorizedAddressAtIndexTx(uint256 transactionId) {
Transaction storage tx = transactions[transactionId];
require(isAssetProxyRegistered[tx.destination]);
- require(isFunctionRemoveAuthorizedAddress(tx.data));
+ require(tx.data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR);
_;
}
@@ -66,7 +66,7 @@ contract AssetProxyOwner is
}
/// @dev Registers or deregisters an AssetProxy to be able to execute
- /// removeAuthorizedAddress without a timelock.
+ /// `removeAuthorizedAddressAtIndex` without a timelock.
/// @param assetProxyContract Address of AssetProxy contract.
/// @param isRegistered Status of approval for AssetProxy contract.
function registerAssetProxy(address assetProxyContract, bool isRegistered)
@@ -78,13 +78,13 @@ contract AssetProxyOwner is
AssetProxyRegistration(assetProxyContract, isRegistered);
}
- /// @dev Allows execution of removeAuthorizedAddress without time lock.
+ /// @dev Allows execution of `removeAuthorizedAddressAtIndex` without time lock.
/// @param transactionId Transaction ID.
- function executeRemoveAuthorizedAddress(uint256 transactionId)
+ function executeRemoveAuthorizedAddressAtIndex(uint256 transactionId)
public
notExecuted(transactionId)
fullyConfirmed(transactionId)
- validRemoveAuthorizedAddressTx(transactionId)
+ validRemoveAuthorizedAddressAtIndexTx(transactionId)
{
Transaction storage tx = transactions[transactionId];
tx.executed = true;
@@ -95,17 +95,4 @@ contract AssetProxyOwner is
tx.executed = false;
}
}
-
- /// @dev Compares first 4 bytes of byte array to removeAuthorizedAddress function selector.
- /// @param data Transaction data.
- /// @return Successful if data is a call to removeAuthorizedAddress.
- function isFunctionRemoveAuthorizedAddress(bytes memory data)
- public
- pure
- returns (bool)
- {
- bytes4 first4Bytes = readFirst4(data);
- require(REMOVE_AUTHORIZED_ADDRESS_SELECTOR == first4Bytes);
- return true;
- }
}
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinAssetProxyDispatcher.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinAssetProxyDispatcher.sol
index f85019012..b8d6c0722 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinAssetProxyDispatcher.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinAssetProxyDispatcher.sol
@@ -19,14 +19,12 @@
pragma solidity ^0.4.24;
import "../../utils/Ownable/Ownable.sol";
-import "../../utils/LibBytes/LibBytes.sol";
import "./libs/LibExchangeErrors.sol";
import "./mixins/MAssetProxyDispatcher.sol";
import "../AssetProxy/interfaces/IAssetProxy.sol";
contract MixinAssetProxyDispatcher is
Ownable,
- LibBytes,
LibExchangeErrors,
MAssetProxyDispatcher
{
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol
index c227d210f..b207b3e57 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol
@@ -32,7 +32,6 @@ import "./mixins/MAssetProxyDispatcher.sol";
contract MixinExchangeCore is
LibConstants,
- LibBytes,
LibMath,
LibOrder,
LibFillResults,
@@ -42,6 +41,8 @@ contract MixinExchangeCore is
MSignatureValidator,
MTransactions
{
+ using LibBytes for bytes;
+
// Mapping of orderHash => amount of takerAsset already bought by maker
mapping (bytes32 => uint256) public filled;
@@ -411,8 +412,8 @@ contract MixinExchangeCore is
)
private
{
- uint8 makerAssetProxyId = uint8(popLastByte(order.makerAssetData));
- uint8 takerAssetProxyId = uint8(popLastByte(order.takerAssetData));
+ uint8 makerAssetProxyId = uint8(order.makerAssetData.popLastByte());
+ uint8 takerAssetProxyId = uint8(order.takerAssetData.popLastByte());
bytes memory zrxAssetData = ZRX_ASSET_DATA;
dispatchTransferFrom(
order.makerAssetData,
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol
index 82325a29f..e36fcc2c5 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol
@@ -27,7 +27,6 @@ import "./mixins/MAssetProxyDispatcher.sol";
contract MixinMatchOrders is
LibConstants,
- LibBytes,
LibMath,
LibExchangeErrors,
MAssetProxyDispatcher,
@@ -35,6 +34,7 @@ contract MixinMatchOrders is
MMatchOrders,
MTransactions
{
+ using LibBytes for bytes;
/// @dev Match two complementary orders that have a profitable spread.
/// Each order is filled at their respective price point. However, the calculations are
@@ -242,8 +242,8 @@ contract MixinMatchOrders is
)
private
{
- uint8 leftMakerAssetProxyId = uint8(popLastByte(leftOrder.makerAssetData));
- uint8 rightMakerAssetProxyId = uint8(popLastByte(rightOrder.makerAssetData));
+ uint8 leftMakerAssetProxyId = uint8(leftOrder.makerAssetData.popLastByte());
+ uint8 rightMakerAssetProxyId = uint8(rightOrder.makerAssetData.popLastByte());
bytes memory zrxAssetData = ZRX_ASSET_DATA;
// Order makers and taker
dispatchTransferFrom(
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
index 881d6e7b3..cbb55bfce 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
@@ -26,11 +26,12 @@ import "./interfaces/IWallet.sol";
import "./interfaces/IValidator.sol";
contract MixinSignatureValidator is
- LibBytes,
LibExchangeErrors,
MSignatureValidator,
MTransactions
{
+ using LibBytes for bytes;
+
// Personal message headers
string constant ETH_PERSONAL_MESSAGE = "\x19Ethereum Signed Message:\n32";
string constant TREZOR_PERSONAL_MESSAGE = "\x19Ethereum Signed Message:\n\x20";
@@ -102,7 +103,7 @@ contract MixinSignatureValidator is
);
// Ensure signature is supported
- uint8 signatureTypeRaw = uint8(popLastByte(signature));
+ uint8 signatureTypeRaw = uint8(signature.popLastByte());
require(
signatureTypeRaw < uint8(SignatureType.NSignatureTypes),
SIGNATURE_UNSUPPORTED
@@ -144,8 +145,8 @@ contract MixinSignatureValidator is
LENGTH_65_REQUIRED
);
v = uint8(signature[0]);
- r = readBytes32(signature, 1);
- s = readBytes32(signature, 33);
+ r = signature.readBytes32(1);
+ s = signature.readBytes32(33);
recovered = ecrecover(hash, v, r, s);
isValid = signerAddress == recovered;
return isValid;
@@ -157,8 +158,8 @@ contract MixinSignatureValidator is
LENGTH_65_REQUIRED
);
v = uint8(signature[0]);
- r = readBytes32(signature, 1);
- s = readBytes32(signature, 33);
+ r = signature.readBytes32(1);
+ s = signature.readBytes32(33);
recovered = ecrecover(
keccak256(abi.encodePacked(ETH_PERSONAL_MESSAGE, hash)),
v,
@@ -199,7 +200,9 @@ contract MixinSignatureValidator is
// | 0x14 + x | 1 | Signature type is always "\x06" |
} else if (signatureType == SignatureType.Validator) {
// Pop last 20 bytes off of signature byte array.
- address validatorAddress = popLast20Bytes(signature);
+
+ address validatorAddress = signature.popLast20Bytes();
+
// Ensure signer has approved validator.
if (!allowedValidators[signerAddress][validatorAddress]) {
return false;
@@ -230,8 +233,8 @@ contract MixinSignatureValidator is
LENGTH_65_REQUIRED
);
v = uint8(signature[0]);
- r = readBytes32(signature, 1);
- s = readBytes32(signature, 33);
+ r = signature.readBytes32(1);
+ s = signature.readBytes32(33);
recovered = ecrecover(
keccak256(abi.encodePacked(TREZOR_PERSONAL_MESSAGE, hash)),
v,
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol
index d3d22d48f..20a4a12df 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol
@@ -51,17 +51,27 @@ contract MixinTransactions is
/// @param signerAddress Address of transaction signer.
/// @param data AbiV2 encoded calldata.
/// @return EIP712 hash of the Transaction.
- function hashZeroExTransaction(uint256 salt, address signerAddress, bytes data)
+ function hashZeroExTransaction(
+ uint256 salt,
+ address signerAddress,
+ bytes memory data
+ )
internal
pure
- returns (bytes32)
+ returns (bytes32 result)
{
- return keccak256(abi.encode(
- EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,
- salt,
- signerAddress,
- keccak256(data)
- ));
+ bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;
+ bytes32 dataHash = keccak256(data);
+ assembly {
+ let memPtr := mload(64)
+ mstore(memPtr, schemaHash)
+ mstore(add(memPtr, 32), salt)
+ mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))
+ mstore(add(memPtr, 96), dataHash)
+ result := keccak256(memPtr, 128)
+ }
+
+ return result;
}
/// @dev Executes an exchange method call in the context of signer.
diff --git a/packages/contracts/src/contracts/current/test/TestAssetProxyOwner/TestAssetProxyOwner.sol b/packages/contracts/src/contracts/current/test/TestAssetProxyOwner/TestAssetProxyOwner.sol
new file mode 100644
index 000000000..2abcd17a0
--- /dev/null
+++ b/packages/contracts/src/contracts/current/test/TestAssetProxyOwner/TestAssetProxyOwner.sol
@@ -0,0 +1,56 @@
+/*
+
+ Copyright 2018 ZeroEx Intl.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+pragma solidity ^0.4.24;
+
+import "../../protocol/AssetProxyOwner/AssetProxyOwner.sol";
+
+contract TestAssetProxyOwner is
+ AssetProxyOwner
+{
+ constructor(
+ address[] memory _owners,
+ address[] memory _assetProxyContracts,
+ uint256 _required,
+ uint256 _secondsTimeLocked
+ )
+ public
+ AssetProxyOwner(_owners, _assetProxyContracts, _required, _secondsTimeLocked)
+ {
+ }
+
+ function testValidRemoveAuthorizedAddressAtIndexTx(uint256 id)
+ public
+ validRemoveAuthorizedAddressAtIndexTx(id)
+ returns (bool)
+ {
+ // Do nothing. We expect reverts through the modifier
+ return true;
+ }
+
+ /// @dev Compares first 4 bytes of byte array to `removeAuthorizedAddressAtIndex` function selector.
+ /// @param data Transaction data.
+ /// @return Successful if data is a call to `removeAuthorizedAddressAtIndex`.
+ function isFunctionRemoveAuthorizedAddressAtIndex(bytes memory data)
+ public
+ pure
+ returns (bool)
+ {
+ return data.readBytes4(0) == REMOVE_AUTHORIZED_ADDRESS_AT_INDEX_SELECTOR;
+ }
+}
diff --git a/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol b/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol
index 6f1898acd..f45faaf36 100644
--- a/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol
+++ b/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol
@@ -21,9 +21,9 @@ pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
-contract TestLibBytes is
- LibBytes
-{
+contract TestLibBytes {
+
+ using LibBytes for bytes;
/// @dev Pops the last byte off of a byte array by modifying its length.
/// @param b Byte array that will be modified.
@@ -33,7 +33,7 @@ contract TestLibBytes is
pure
returns (bytes memory, bytes1 result)
{
- result = popLastByte(b);
+ result = b.popLastByte();
return (b, result);
}
@@ -45,7 +45,7 @@ contract TestLibBytes is
pure
returns (bytes memory, address result)
{
- result = popLast20Bytes(b);
+ result = b.popLast20Bytes();
return (b, result);
}
@@ -53,12 +53,23 @@ contract TestLibBytes is
/// @param lhs First byte array to compare.
/// @param rhs Second byte array to compare.
/// @return True if arrays are the same. False otherwise.
- function publicAreBytesEqual(bytes memory lhs, bytes memory rhs)
+ function publicEquals(bytes memory lhs, bytes memory rhs)
public
pure
returns (bool equal)
{
- equal = areBytesEqual(lhs, rhs);
+ equal = lhs.equals(rhs);
+ return equal;
+ }
+
+ function publicEqualsPop1(bytes memory lhs, bytes memory rhs)
+ public
+ pure
+ returns (bool equal)
+ {
+ lhs.popLastByte();
+ rhs.popLastByte();
+ equal = lhs.equals(rhs);
return equal;
}
@@ -73,7 +84,7 @@ contract TestLibBytes is
pure
returns (bytes memory)
{
- deepCopyBytes(dest, source);
+ LibBytes.deepCopyBytes(dest, source);
return dest;
}
@@ -89,7 +100,7 @@ contract TestLibBytes is
pure
returns (address result)
{
- result = readAddress(b, index);
+ result = b.readAddress(index);
return result;
}
@@ -106,7 +117,7 @@ contract TestLibBytes is
pure
returns (bytes memory)
{
- writeAddress(b, index, input);
+ b.writeAddress(index, input);
return b;
}
@@ -122,7 +133,7 @@ contract TestLibBytes is
pure
returns (bytes32 result)
{
- result = readBytes32(b, index);
+ result = b.readBytes32(index);
return result;
}
@@ -139,7 +150,7 @@ contract TestLibBytes is
pure
returns (bytes memory)
{
- writeBytes32(b, index, input);
+ b.writeBytes32(index, input);
return b;
}
@@ -155,7 +166,7 @@ contract TestLibBytes is
pure
returns (uint256 result)
{
- result = readUint256(b, index);
+ result = b.readUint256(index);
return result;
}
@@ -172,19 +183,23 @@ contract TestLibBytes is
pure
returns (bytes memory)
{
- writeUint256(b, index, input);
+ b.writeUint256(index, input);
return b;
}
- /// @dev Reads the first 4 bytes from a byte array of arbitrary length.
- /// @param b Byte array to read first 4 bytes from.
- /// @return First 4 bytes of data.
- function publicReadFirst4(bytes memory b)
+ /// @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
pure
returns (bytes4 result)
{
- result = readFirst4(b);
+ result = b.readBytes4(index);
return result;
}
@@ -192,7 +207,7 @@ contract TestLibBytes is
/// @param b Byte array containing nested bytes.
/// @param index Index of nested bytes.
/// @return result Nested bytes.
- function publicReadBytes(
+ function publicReadBytesWithLength(
bytes memory b,
uint256 index
)
@@ -200,7 +215,7 @@ contract TestLibBytes is
pure
returns (bytes memory result)
{
- result = readBytes(b, index);
+ result = b.readBytesWithLength(index);
return result;
}
@@ -209,7 +224,7 @@ contract TestLibBytes is
/// @param index Index in byte array of <input>.
/// @param input bytes to insert.
/// @return b Updated input byte array
- function publicWriteBytes(
+ function publicWriteBytesWithLength(
bytes memory b,
uint256 index,
bytes memory input
@@ -218,7 +233,37 @@ contract TestLibBytes is
pure
returns (bytes memory)
{
- writeBytes(b, index, input);
+ b.writeBytesWithLength(index, input);
return b;
}
+
+ /// @dev Copies a block of memory from one location to another.
+ /// @param mem Memory contents we want to apply memCopy to
+ /// @param dest Destination offset into <mem>.
+ /// @param source Source offset into <mem>.
+ /// @param length Length of bytes to copy from <source> to <dest>
+ /// @return mem Memory contents after calling memCopy.
+ function testMemcpy(
+ bytes mem,
+ uint256 dest,
+ uint256 source,
+ uint256 length
+ )
+ public // not external, we need input in memory
+ pure
+ returns (bytes)
+ {
+ // Sanity check. Overflows are not checked.
+ require(source + length <= mem.length);
+ require(dest + length <= mem.length);
+
+ // Get pointer to memory contents
+ uint256 offset = mem.contentAddress();
+
+ // Execute memCopy adjusted for memory array location
+ LibBytes.memCopy(offset + dest, offset + source, length);
+
+ // Return modified memory contents
+ return mem;
+ }
}
diff --git a/packages/contracts/src/contracts/current/test/TestLibMem/TestLibMem.sol b/packages/contracts/src/contracts/current/test/TestLibMem/TestLibMem.sol
deleted file mode 100644
index b7e2e06b8..000000000
--- a/packages/contracts/src/contracts/current/test/TestLibMem/TestLibMem.sol
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-
- Copyright 2018 ZeroEx Intl.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-*/
-
-pragma solidity ^0.4.24;
-
-import "../../utils/LibMem/LibMem.sol";
-
-contract TestLibMem is
- LibMem
-{
-
- /// @dev Copies a block of memory from one location to another.
- /// @param mem Memory contents we want to apply memCopy to
- /// @param dest Destination offset into <mem>.
- /// @param source Source offset into <mem>.
- /// @param length Length of bytes to copy from <source> to <dest>
- /// @return mem Memory contents after calling memCopy.
- function testMemcpy(
- bytes mem,
- uint256 dest,
- uint256 source,
- uint256 length
- )
- public // not external, we need input in memory
- pure
- returns (bytes)
- {
- // Sanity check. Overflows are not checked.
- require(source + length <= mem.length);
- require(dest + length <= mem.length);
-
- // Get pointer to memory contents
- uint256 offset = getMemAddress(mem) + 32;
-
- // Execute memCopy adjusted for memory array location
- memCopy(offset + dest, offset + source, length);
-
- // Return modified memory contents
- return mem;
- }
-}
diff --git a/packages/contracts/src/contracts/current/test/TestWallet/TestWallet.sol b/packages/contracts/src/contracts/current/test/TestWallet/TestWallet.sol
index aca74b409..17dee9e9c 100644
--- a/packages/contracts/src/contracts/current/test/TestWallet/TestWallet.sol
+++ b/packages/contracts/src/contracts/current/test/TestWallet/TestWallet.sol
@@ -22,9 +22,9 @@ import "../../protocol/Exchange/interfaces/IWallet.sol";
import "../../utils/LibBytes/LibBytes.sol";
contract TestWallet is
- IWallet,
- LibBytes
+ IWallet
{
+ using LibBytes for bytes;
string constant LENGTH_65_REQUIRED = "LENGTH_65_REQUIRED";
@@ -56,8 +56,8 @@ contract TestWallet is
);
uint8 v = uint8(eip712Signature[0]);
- bytes32 r = readBytes32(eip712Signature, 1);
- bytes32 s = readBytes32(eip712Signature, 33);
+ bytes32 r = eip712Signature.readBytes32(1);
+ bytes32 s = eip712Signature.readBytes32(33);
address recoveredAddress = ecrecover(hash, v, r, s);
isValid = WALLET_OWNER == recoveredAddress;
return isValid;
diff --git a/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol b/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol
index 10d7ce41a..e4cbf318b 100644
--- a/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol
+++ b/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol
@@ -18,11 +18,8 @@
pragma solidity ^0.4.24;
-import "../LibMem/LibMem.sol";
-
-contract LibBytes is
- LibMem
-{
+library LibBytes {
+ using LibBytes for bytes;
// Revert reasons
string constant GREATER_THAN_ZERO_LENGTH_REQUIRED = "GREATER_THAN_ZERO_LENGTH_REQUIRED";
@@ -31,6 +28,187 @@ contract LibBytes is
string constant GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED = "GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED";
string constant GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED = "GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED";
string constant GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED = "GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED";
+ string constant FROM_LESS_THAN_TO_REQUIRED = "FROM_LESS_THAN_TO_REQUIRED";
+ string constant TO_LESS_THAN_LENGTH_REQUIRED = "TO_LESS_THAN_LENGTH_REQUIRED";
+
+ /// @dev Gets the memory address for a byte array.
+ /// @param input Byte array to lookup.
+ /// @return memoryAddress Memory address of byte array. This
+ /// points to the header of the byte array which contains
+ /// the length.
+ function rawAddress(bytes memory input)
+ internal
+ pure
+ returns (uint256 memoryAddress)
+ {
+ assembly {
+ memoryAddress := input
+ }
+ return memoryAddress;
+ }
+
+ /// @dev Gets the memory address for the contents of a byte array.
+ /// @param input Byte array to lookup.
+ /// @return memoryAddress Memory address of the contents of the byte array.
+ function contentAddress(bytes memory input)
+ internal
+ pure
+ returns (uint256 memoryAddress)
+ {
+ assembly {
+ memoryAddress := add(input, 32)
+ }
+ return memoryAddress;
+ }
+
+ /// @dev Copies `length` bytes from memory location `source` to `dest`.
+ /// @param dest memory address to copy bytes to.
+ /// @param source memory address to copy bytes from.
+ /// @param length number of bytes to copy.
+ function memCopy(
+ uint256 dest,
+ uint256 source,
+ uint256 length
+ )
+ internal
+ pure
+ {
+ if (length < 32) {
+ // Handle a partial word by reading destination and masking
+ // off the bits we are interested in.
+ // This correctly handles overlap, zero lengths and source == dest
+ assembly {
+ let mask := sub(exp(256, sub(32, length)), 1)
+ let s := and(mload(source), not(mask))
+ let d := and(mload(dest), mask)
+ mstore(dest, or(s, d))
+ }
+ } else {
+ // Skip the O(length) loop when source == dest.
+ if (source == dest) {
+ return;
+ }
+
+ // For large copies we copy whole words at a time. The final
+ // word is aligned to the end of the range (instead of after the
+ // previous) to handle partial words. So a copy will look like this:
+ //
+ // ####
+ // ####
+ // ####
+ // ####
+ //
+ // We handle overlap in the source and destination range by
+ // changing the copying direction. This prevents us from
+ // overwriting parts of source that we still need to copy.
+ //
+ // This correctly handles source == dest
+ //
+ if (source > dest) {
+ assembly {
+ // We subtract 32 from `sEnd` and `dEnd` because it
+ // is easier to compare with in the loop, and these
+ // are also the addresses we need for copying the
+ // last bytes.
+ length := sub(length, 32)
+ let sEnd := add(source, length)
+ let dEnd := add(dest, length)
+
+ // Remember the last 32 bytes of source
+ // This needs to be done here and not after the loop
+ // because we may have overwritten the last bytes in
+ // source already due to overlap.
+ let last := mload(sEnd)
+
+ // Copy whole words front to back
+ // Note: the first check is always true,
+ // this could have been a do-while loop.
+ for {} lt(source, sEnd) {} {
+ mstore(dest, mload(source))
+ source := add(source, 32)
+ dest := add(dest, 32)
+ }
+
+ // Write the last 32 bytes
+ mstore(dEnd, last)
+ }
+ } else {
+ assembly {
+ // We subtract 32 from `sEnd` and `dEnd` because those
+ // are the starting points when copying a word at the end.
+ length := sub(length, 32)
+ let sEnd := add(source, length)
+ let dEnd := add(dest, length)
+
+ // Remember the first 32 bytes of source
+ // This needs to be done here and not after the loop
+ // because we may have overwritten the first bytes in
+ // source already due to overlap.
+ let first := mload(source)
+
+ // Copy whole words back to front
+ // We use a signed comparisson here to allow dEnd to become
+ // negative (happens when source and dest < 32). Valid
+ // addresses in local memory will never be larger than
+ // 2**255, so they can be safely re-interpreted as signed.
+ // Note: the first check is always true,
+ // this could have been a do-while loop.
+ for {} slt(dest, dEnd) {} {
+ mstore(dEnd, mload(sEnd))
+ sEnd := sub(sEnd, 32)
+ dEnd := sub(dEnd, 32)
+ }
+
+ // Write the first 32 bytes
+ mstore(dest, first)
+ }
+ }
+ }
+ }
+
+ /// @dev Returns a slices from a byte array.
+ /// @param b The byte array to take a slice from.
+ /// @param from The starting index for the slice (inclusive).
+ /// @param to The final index for the slice (exclusive).
+ /// @return result The slice containing bytes at indices [from, to)
+ function slice(bytes memory b, uint256 from, uint256 to)
+ internal
+ pure
+ returns (bytes memory result)
+ {
+ require(from <= to, FROM_LESS_THAN_TO_REQUIRED);
+ require(to < b.length, TO_LESS_THAN_LENGTH_REQUIRED);
+
+ // Create a new bytes structure and copy contents
+ result = new bytes(to - from);
+ memCopy(
+ result.contentAddress(),
+ b.contentAddress() + from,
+ result.length);
+ return result;
+ }
+
+ /// @dev Returns a slice from a byte array without preserving the input.
+ /// @param b The byte array to take a slice from. Will be destroyed in the process.
+ /// @param from The starting index for the slice (inclusive).
+ /// @param to The final index for the slice (exclusive).
+ /// @return result The slice containing bytes at indices [from, to)
+ /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.
+ function sliceDestructive(bytes memory b, uint256 from, uint256 to)
+ internal
+ pure
+ returns (bytes memory result)
+ {
+ require(from <= to, FROM_LESS_THAN_TO_REQUIRED);
+ require(to < b.length, TO_LESS_THAN_LENGTH_REQUIRED);
+
+ // Create a new bytes structure around [from, to) in-place.
+ assembly {
+ result := add(b, from)
+ mstore(result, sub(to, from))
+ }
+ return result;
+ }
/// @dev Pops the last byte off of a byte array by modifying its length.
/// @param b Byte array that will be modified.
@@ -80,6 +258,24 @@ contract LibBytes is
return result;
}
+ /// @dev Tests equality of two byte arrays.
+ /// @param lhs First byte array to compare.
+ /// @param rhs Second byte array to compare.
+ /// @return True if arrays are the same. False otherwise.
+ function equals(
+ bytes memory lhs,
+ bytes memory rhs
+ )
+ internal
+ pure
+ returns (bool equal)
+ {
+ // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.
+ // We early exit on unequal lengths, but keccak would also correctly
+ // handle this.
+ return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);
+ }
+
/// @dev Reads an address from a position in a byte array.
/// @param b Byte array containing an address.
/// @param index Index in byte array of address.
@@ -145,6 +341,10 @@ contract LibBytes is
// 2. Load 32-byte word from memory
// 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address
let neighbors := and(mload(add(b, index)), 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)
+
+ // Make sure input address is clean.
+ // (Solidity does not guarantee this)
+ input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)
// Store the neighbors and address into memory
mstore(add(b, index), xor(input, neighbors))
@@ -234,20 +434,26 @@ contract LibBytes is
writeBytes32(b, index, bytes32(input));
}
- /// @dev Reads the first 4 bytes from a byte array of arbitrary length.
- /// @param b Byte array to read first 4 bytes from.
- /// @return First 4 bytes of data.
- function readFirst4(bytes memory b)
+ /// @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
pure
returns (bytes4 result)
{
require(
- b.length >= 4,
+ b.length >= index + 4,
GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED
);
assembly {
result := mload(add(b, 32))
+ // Solidity does not require us to clean the trailing bytes.
+ // We do it anyway
+ result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
}
return result;
}
@@ -256,7 +462,7 @@ contract LibBytes is
/// @param b Byte array containing nested bytes.
/// @param index Index of nested bytes.
/// @return result Nested bytes.
- function readBytes(
+ function readBytesWithLength(
bytes memory b,
uint256 index
)
@@ -278,8 +484,8 @@ contract LibBytes is
// Allocate memory and copy value to result
result = new bytes(nestedBytesLength);
memCopy(
- getMemAddress(result) + 32, // +32 skips array length
- getMemAddress(b) + index + 32,
+ result.contentAddress(),
+ b.contentAddress() + index,
nestedBytesLength
);
@@ -290,7 +496,7 @@ contract LibBytes is
/// @param b Byte array to insert <input> into.
/// @param index Index in byte array of <input>.
/// @param input bytes to insert.
- function writeBytes(
+ function writeBytesWithLength(
bytes memory b,
uint256 index,
bytes memory input
@@ -307,47 +513,12 @@ contract LibBytes is
// Copy <input> into <b>
memCopy(
- getMemAddress(b) + 32 + index, // +32 to skip length of <b>
- getMemAddress(input), // includes length of <input>
- input.length + 32 // +32 bytes to store <input> length
+ b.contentAddress() + index,
+ input.rawAddress(), // includes length of <input>
+ input.length + 32 // +32 bytes to store <input> length
);
}
- /// @dev Tests equality of two byte arrays.
- /// @param lhs First byte array to compare.
- /// @param rhs Second byte array to compare.
- /// @return True if arrays are the same. False otherwise.
- function areBytesEqual(
- bytes memory lhs,
- bytes memory rhs
- )
- internal
- pure
- returns (bool equal)
- {
- assembly {
- // Get the number of words occupied by <lhs>
- let lenFullWords := div(add(mload(lhs), 0x1F), 0x20)
-
- // Add 1 to the number of words, to account for the length field
- lenFullWords := add(lenFullWords, 0x1)
-
- // Test equality word-by-word.
- // Terminates early if there is a mismatch.
- for {let i := 0} lt(i, lenFullWords) {i := add(i, 1)} {
- let lhsWord := mload(add(lhs, mul(i, 0x20)))
- let rhsWord := mload(add(rhs, mul(i, 0x20)))
- equal := eq(lhsWord, rhsWord)
- if eq(equal, 0) {
- // Break
- i := lenFullWords
- }
- }
- }
-
- return equal;
- }
-
/// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.
/// @param dest Byte array that will be overwritten with source bytes.
/// @param source Byte array to copy onto dest bytes.
@@ -365,8 +536,8 @@ contract LibBytes is
GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED
);
memCopy(
- getMemAddress(dest) + 32, // +32 to skip length of <dest>
- getMemAddress(source) + 32, // +32 to skip length of <source>
+ dest.contentAddress(),
+ source.contentAddress(),
sourceLen
);
}
diff --git a/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol b/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol
deleted file mode 100644
index 97fb5fb0f..000000000
--- a/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
-
- Copyright 2018 ZeroEx Intl.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-*/
-
-pragma solidity ^0.4.24;
-
-contract LibMem
-{
-
- /// @dev Gets the memory address for a byte array.
- /// @param input Byte array to lookup.
- /// @return memoryAddress Memory address of byte array.
- function getMemAddress(bytes memory input)
- internal
- pure
- returns (uint256 memoryAddress)
- {
- assembly {
- memoryAddress := input
- }
- return memoryAddress;
- }
-
- /// @dev Copies `length` bytes from memory location `source` to `dest`.
- /// @param dest memory address to copy bytes to.
- /// @param source memory address to copy bytes from.
- /// @param length number of bytes to copy.
- function memCopy(
- uint256 dest,
- uint256 source,
- uint256 length
- )
- internal
- pure
- {
- if (length < 32) {
- // Handle a partial word by reading destination and masking
- // off the bits we are interested in.
- // This correctly handles overlap, zero lengths and source == dest
- assembly {
- let mask := sub(exp(256, sub(32, length)), 1)
- let s := and(mload(source), not(mask))
- let d := and(mload(dest), mask)
- mstore(dest, or(s, d))
- }
- } else {
- // Skip the O(length) loop when source == dest.
- if (source == dest) {
- return;
- }
-
- // For large copies we copy whole words at a time. The final
- // word is aligned to the end of the range (instead of after the
- // previous) to handle partial words. So a copy will look like this:
- //
- // ####
- // ####
- // ####
- // ####
- //
- // We handle overlap in the source and destination range by
- // changing the copying direction. This prevents us from
- // overwriting parts of source that we still need to copy.
- //
- // This correctly handles source == dest
- //
- if (source > dest) {
- assembly {
- // We subtract 32 from `sEnd` and `dEnd` because it
- // is easier to compare with in the loop, and these
- // are also the addresses we need for copying the
- // last bytes.
- length := sub(length, 32)
- let sEnd := add(source, length)
- let dEnd := add(dest, length)
-
- // Remember the last 32 bytes of source
- // This needs to be done here and not after the loop
- // because we may have overwritten the last bytes in
- // source already due to overlap.
- let last := mload(sEnd)
-
- // Copy whole words front to back
- // Note: the first check is always true,
- // this could have been a do-while loop.
- for {} lt(source, sEnd) {} {
- mstore(dest, mload(source))
- source := add(source, 32)
- dest := add(dest, 32)
- }
-
- // Write the last 32 bytes
- mstore(dEnd, last)
- }
- } else {
- assembly {
- // We subtract 32 from `sEnd` and `dEnd` because those
- // are the starting points when copying a word at the end.
- length := sub(length, 32)
- let sEnd := add(source, length)
- let dEnd := add(dest, length)
-
- // Remember the first 32 bytes of source
- // This needs to be done here and not after the loop
- // because we may have overwritten the first bytes in
- // source already due to overlap.
- let first := mload(source)
-
- // Copy whole words back to front
- // We use a signed comparisson here to allow dEnd to become
- // negative (happens when source and dest < 32). Valid
- // addresses in local memory will never be larger than
- // 2**255, so they can be safely re-interpreted as signed.
- // Note: the first check is always true,
- // this could have been a do-while loop.
- for {} slt(dest, dEnd) {} {
- mstore(dEnd, mload(sEnd))
- sEnd := sub(sEnd, 32)
- dEnd := sub(dEnd, 32)
- }
-
- // Write the first 32 bytes
- mstore(dest, first)
- }
- }
- }
- }
-}
diff --git a/packages/contracts/src/contracts/current/utils/Ownable/Ownable.sol b/packages/contracts/src/contracts/current/utils/Ownable/Ownable.sol
index 048fdb46f..99b93d0d2 100644
--- a/packages/contracts/src/contracts/current/utils/Ownable/Ownable.sol
+++ b/packages/contracts/src/contracts/current/utils/Ownable/Ownable.sol
@@ -13,6 +13,9 @@ import "./IOwnable.sol";
contract Ownable is IOwnable {
address public owner;
+ // Revert reasons
+ string constant ONLY_CONTRACT_OWNER = "ONLY_CONTRACT_OWNER";
+
constructor ()
public
{
@@ -22,7 +25,7 @@ contract Ownable is IOwnable {
modifier onlyOwner() {
require(
msg.sender == owner,
- 'ONLY_CONTRACT_OWNER'
+ ONLY_CONTRACT_OWNER
);
_;
}
diff --git a/packages/contracts/src/utils/artifacts.ts b/packages/contracts/src/utils/artifacts.ts
index 4375d87c6..a46bab9ae 100644
--- a/packages/contracts/src/utils/artifacts.ts
+++ b/packages/contracts/src/utils/artifacts.ts
@@ -13,8 +13,8 @@ import * as MultiSigWallet from '../artifacts/MultiSigWallet.json';
import * as MultiSigWalletWithTimeLock from '../artifacts/MultiSigWalletWithTimeLock.json';
import * as TestAssetDataDecoders from '../artifacts/TestAssetDataDecoders.json';
import * as TestAssetProxyDispatcher from '../artifacts/TestAssetProxyDispatcher.json';
+import * as TestAssetProxyOwner from '../artifacts/TestAssetProxyOwner.json';
import * as TestLibBytes from '../artifacts/TestLibBytes.json';
-import * as TestLibMem from '../artifacts/TestLibMem.json';
import * as TestLibs from '../artifacts/TestLibs.json';
import * as TestSignatureValidator from '../artifacts/TestSignatureValidator.json';
import * as TestValidator from '../artifacts/TestValidator.json';
@@ -37,10 +37,10 @@ export const artifacts = {
MixinAuthorizable: (MixinAuthorizable as any) as ContractArtifact,
MultiSigWallet: (MultiSigWallet as any) as ContractArtifact,
MultiSigWalletWithTimeLock: (MultiSigWalletWithTimeLock as any) as ContractArtifact,
+ TestAssetProxyOwner: (TestAssetProxyOwner as any) as ContractArtifact,
TestAssetProxyDispatcher: (TestAssetProxyDispatcher as any) as ContractArtifact,
TestAssetDataDecoders: (TestAssetDataDecoders as any) as ContractArtifact,
TestLibBytes: (TestLibBytes as any) as ContractArtifact,
- TestLibMem: (TestLibMem as any) as ContractArtifact,
TestLibs: (TestLibs as any) as ContractArtifact,
TestSignatureValidator: (TestSignatureValidator as any) as ContractArtifact,
TestValidator: (TestValidator as any) as ContractArtifact,
diff --git a/packages/contracts/src/utils/multi_sig_wrapper.ts b/packages/contracts/src/utils/multi_sig_wrapper.ts
index f0098bd5e..b0d4fa8ab 100644
--- a/packages/contracts/src/utils/multi_sig_wrapper.ts
+++ b/packages/contracts/src/utils/multi_sig_wrapper.ts
@@ -40,13 +40,15 @@ export class MultiSigWrapper {
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return tx;
}
- public async executeRemoveAuthorizedAddressAsync(
+ public async executeRemoveAuthorizedAddressAtIndexAsync(
txId: BigNumber,
from: string,
): Promise<TransactionReceiptWithDecodedLogs> {
// tslint:disable-next-line:no-unnecessary-type-assertion
const txHash = await (this
- ._multiSig as AssetProxyOwnerContract).executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from });
+ ._multiSig as AssetProxyOwnerContract).executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, {
+ from,
+ });
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
return tx;
}
diff --git a/packages/contracts/src/utils/types.ts b/packages/contracts/src/utils/types.ts
index 03eb5c9b2..835e7dda8 100644
--- a/packages/contracts/src/utils/types.ts
+++ b/packages/contracts/src/utils/types.ts
@@ -92,7 +92,6 @@ export enum ContractName {
Arbitrage = 'Arbitrage',
TestAssetDataDecoders = 'TestAssetDataDecoders',
TestAssetProxyDispatcher = 'TestAssetProxyDispatcher',
- TestLibMem = 'TestLibMem',
TestLibs = 'TestLibs',
TestSignatureValidator = 'TestSignatureValidator',
ERC20Proxy = 'ERC20Proxy',