aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src
diff options
context:
space:
mode:
authorRemco Bloemen <Recmo@users.noreply.github.com>2018-06-23 20:08:40 +0800
committerGitHub <noreply@github.com>2018-06-23 20:08:40 +0800
commitd621e4201d0c9729bb5a999c77e32141bb929279 (patch)
tree6446c44534fe82d809aba631cf3dbe5c6b35e5dc /packages/contracts/src
parent26cacfa247fcd07368d3a5bfb7a99aa0b47797ef (diff)
parent82af1df3c3d62ab0a0dd4687bf9bb65d3b261054 (diff)
downloaddexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.tar
dexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.tar.gz
dexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.tar.bz2
dexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.tar.lz
dexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.tar.xz
dexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.tar.zst
dexon-sol-tools-d621e4201d0c9729bb5a999c77e32141bb929279.zip
Merge pull request #698 from 0xProject/fix/contracts/using-libbytes
Fixes and refactoring regarding LibBytes
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/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
18 files changed, 406 insertions, 332 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/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 296c6c856..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 is allowed to call this method."
+ 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 7a1f92afd..5dfac64fc 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',