aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contracts')
-rw-r--r--packages/contracts/package.json24
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/ERC20Proxy.sol59
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/ERC721Proxy.sol72
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol81
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol94
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibAssetProxyErrors.sol4
-rw-r--r--packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibTransferErrors.sol25
-rw-r--r--packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol22
8 files changed, 230 insertions, 151 deletions
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index 2495795dc..8807c727e 100644
--- a/packages/contracts/package.json
+++ b/packages/contracts/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "contracts",
- "version": "2.1.29",
+ "version": "2.1.33",
"engines": {
"node": ">=6.12"
},
@@ -46,11 +46,11 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md",
"devDependencies": {
- "@0xproject/abi-gen": "^0.3.0",
- "@0xproject/dev-utils": "^0.4.2",
- "@0xproject/tslint-config": "^0.4.18",
+ "@0xproject/abi-gen": "^0.3.2",
+ "@0xproject/dev-utils": "^0.4.4",
+ "@0xproject/tslint-config": "^0.4.20",
"@0xproject/subproviders": "^0.10.1",
- "@0xproject/sol-cov": "^0.0.11",
+ "@0xproject/sol-cov": "^0.1.1",
"@types/lodash": "4.14.104",
"@types/bn.js": "^4.11.0",
"@types/node": "^8.0.53",
@@ -71,18 +71,18 @@
"yargs": "^10.0.3"
},
"dependencies": {
- "@0xproject/base-contract": "^0.3.2",
- "@0xproject/order-utils": "^0.0.6",
- "@0xproject/sol-compiler": "^0.5.0",
+ "@0xproject/base-contract": "^0.3.4",
+ "@0xproject/order-utils": "^1.0.0",
+ "@0xproject/sol-compiler": "^0.5.2",
"@0xproject/types": "^1.0.0",
- "@0xproject/typescript-typings": "^0.3.2",
- "@0xproject/utils": "^0.6.2",
- "@0xproject/web3-wrapper": "^0.6.4",
+ "@0xproject/typescript-typings": "^0.4.1",
+ "@0xproject/utils": "^0.7.1",
+ "@0xproject/web3-wrapper": "^0.7.1",
"ethereum-types": "^0.0.1",
"bn.js": "^4.11.8",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-util": "^5.1.1",
- "ethers": "^3.0.15",
+ "ethers": "3.0.22",
"lodash": "^4.17.4",
"web3": "^0.20.0"
}
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC20Proxy.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC20Proxy.sol
index eeddb9707..7ca823d1f 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC20Proxy.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC20Proxy.sol
@@ -22,69 +22,16 @@ pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
import "./MixinAssetProxy.sol";
import "./MixinAuthorizable.sol";
-import "../../tokens/ERC20Token/IERC20Token.sol";
+import "./MixinERC20Transfer.sol";
contract ERC20Proxy is
- LibBytes,
MixinAssetProxy,
- MixinAuthorizable
+ MixinAuthorizable,
+ MixinERC20Transfer
{
-
// Id of this proxy.
uint8 constant PROXY_ID = 1;
- /// @dev Internal version of `transferFrom`.
- /// @param assetData Encoded byte array.
- /// @param from Address to transfer asset from.
- /// @param to Address to transfer asset to.
- /// @param amount Amount of asset to transfer.
- function transferFromInternal(
- bytes memory assetData,
- address from,
- address to,
- uint256 amount
- )
- internal
- {
- // Decode asset data.
- address token = readAddress(assetData, 0);
-
- // Transfer tokens.
- // We do a raw call so we can check the success separate
- // from the return data.
- bool success = token.call(abi.encodeWithSelector(
- IERC20Token(token).transferFrom.selector,
- from,
- to,
- amount
- ));
- require(
- success,
- TRANSFER_FAILED
- );
-
- // Check return data.
- // If there is no return data, we assume the token incorrectly
- // does not return a bool. In this case we expect it to revert
- // on failure, which was handled above.
- // If the token does return data, we require that it is a single
- // value that evaluates to true.
- assembly {
- if returndatasize {
- success := 0
- if eq(returndatasize, 32) {
- // First 64 bytes of memory are reserved scratch space
- returndatacopy(0, 0, 32)
- success := mload(0)
- }
- }
- }
- require(
- success,
- TRANSFER_FAILED
- );
- }
-
/// @dev Gets the proxy id associated with the proxy address.
/// @return Proxy id.
function getProxyId()
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC721Proxy.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC721Proxy.sol
index 861fac2c1..7ff25aea3 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC721Proxy.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/ERC721Proxy.sol
@@ -22,52 +22,16 @@ pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
import "./MixinAssetProxy.sol";
import "./MixinAuthorizable.sol";
-import "../../tokens/ERC721Token/ERC721Token.sol";
+import "./MixinERC721Transfer.sol";
contract ERC721Proxy is
- LibBytes,
MixinAssetProxy,
- MixinAuthorizable
+ MixinAuthorizable,
+ MixinERC721Transfer
{
-
// Id of this proxy.
uint8 constant PROXY_ID = 2;
- /// @dev Internal version of `transferFrom`.
- /// @param assetData Encoded byte array.
- /// @param from Address to transfer asset from.
- /// @param to Address to transfer asset to.
- /// @param amount Amount of asset to transfer.
- function transferFromInternal(
- bytes memory assetData,
- address from,
- address to,
- uint256 amount
- )
- internal
- {
- // There exists only 1 of each token.
- require(
- amount == 1,
- INVALID_AMOUNT
- );
-
- // Decode asset data.
- (
- address token,
- uint256 tokenId,
- bytes memory receiverData
- ) = decodeERC721AssetData(assetData);
-
- // Transfer token. Saves gas by calling safeTransferFrom only
- // when there is receiverData present. Either succeeds or throws.
- if (receiverData.length > 0) {
- ERC721Token(token).safeTransferFrom(from, to, tokenId, receiverData);
- } else {
- ERC721Token(token).transferFrom(from, to, tokenId);
- }
- }
-
/// @dev Gets the proxy id associated with the proxy address.
/// @return Proxy id.
function getProxyId()
@@ -77,34 +41,4 @@ contract ERC721Proxy is
{
return PROXY_ID;
}
-
- /// @dev Decodes ERC721 Asset data.
- /// @param assetData Encoded byte array.
- /// @return proxyId Intended ERC721 proxy id.
- /// @return token ERC721 token address.
- /// @return tokenId ERC721 token id.
- /// @return receiverData Additional data with no specific format, which
- /// is passed to the receiving contract's onERC721Received.
- function decodeERC721AssetData(bytes memory assetData)
- internal
- pure
- returns (
- address token,
- uint256 tokenId,
- bytes memory receiverData
- )
- {
- // Decode asset data.
- token = readAddress(assetData, 0);
- tokenId = readUint256(assetData, 20);
- if (assetData.length > 52) {
- receiverData = readBytes(assetData, 52);
- }
-
- return (
- token,
- tokenId,
- receiverData
- );
- }
}
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol
new file mode 100644
index 000000000..4af39a00b
--- /dev/null
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC20Transfer.sol
@@ -0,0 +1,81 @@
+/*
+
+ 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;
+pragma experimental ABIEncoderV2;
+
+import "../../utils/LibBytes/LibBytes.sol";
+import "../../tokens/ERC20Token/IERC20Token.sol";
+import "./libs/LibTransferErrors.sol";
+
+contract MixinERC20Transfer is
+ LibBytes,
+ LibTransferErrors
+{
+ /// @dev Internal version of `transferFrom`.
+ /// @param assetData Encoded byte array.
+ /// @param from Address to transfer asset from.
+ /// @param to Address to transfer asset to.
+ /// @param amount Amount of asset to transfer.
+ function transferFromInternal(
+ bytes memory assetData,
+ address from,
+ address to,
+ uint256 amount
+ )
+ internal
+ {
+ // Decode asset data.
+ address token = readAddress(assetData, 0);
+
+ // Transfer tokens.
+ // We do a raw call so we can check the success separate
+ // from the return data.
+ bool success = token.call(abi.encodeWithSelector(
+ IERC20Token(token).transferFrom.selector,
+ from,
+ to,
+ amount
+ ));
+ require(
+ success,
+ TRANSFER_FAILED
+ );
+
+ // Check return data.
+ // If there is no return data, we assume the token incorrectly
+ // does not return a bool. In this case we expect it to revert
+ // on failure, which was handled above.
+ // If the token does return data, we require that it is a single
+ // value that evaluates to true.
+ assembly {
+ if returndatasize {
+ success := 0
+ if eq(returndatasize, 32) {
+ // First 64 bytes of memory are reserved scratch space
+ returndatacopy(0, 0, 32)
+ success := mload(0)
+ }
+ }
+ }
+ require(
+ success,
+ TRANSFER_FAILED
+ );
+ }
+}
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol
new file mode 100644
index 000000000..d09aba599
--- /dev/null
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/MixinERC721Transfer.sol
@@ -0,0 +1,94 @@
+/*
+
+ 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;
+pragma experimental ABIEncoderV2;
+
+import "../../utils/LibBytes/LibBytes.sol";
+import "../../tokens/ERC721Token/ERC721Token.sol";
+import "./libs/LibTransferErrors.sol";
+
+contract MixinERC721Transfer is
+ LibBytes,
+ LibTransferErrors
+{
+ /// @dev Internal version of `transferFrom`.
+ /// @param assetData Encoded byte array.
+ /// @param from Address to transfer asset from.
+ /// @param to Address to transfer asset to.
+ /// @param amount Amount of asset to transfer.
+ function transferFromInternal(
+ bytes memory assetData,
+ address from,
+ address to,
+ uint256 amount
+ )
+ internal
+ {
+ // There exists only 1 of each token.
+ require(
+ amount == 1,
+ INVALID_AMOUNT
+ );
+
+ // Decode asset data.
+ (
+ address token,
+ uint256 tokenId,
+ bytes memory receiverData
+ ) = decodeERC721AssetData(assetData);
+
+ // Transfer token. Saves gas by calling safeTransferFrom only
+ // when there is receiverData present. Either succeeds or throws.
+ if (receiverData.length > 0) {
+ ERC721Token(token).safeTransferFrom(from, to, tokenId, receiverData);
+ } else {
+ ERC721Token(token).transferFrom(from, to, tokenId);
+ }
+ }
+
+ /// @dev Decodes ERC721 Asset data.
+ /// @param assetData Encoded byte array.
+ /// @return proxyId Intended ERC721 proxy id.
+ /// @return token ERC721 token address.
+ /// @return tokenId ERC721 token id.
+ /// @return receiverData Additional data with no specific format, which
+ /// is passed to the receiving contract's onERC721Received.
+ function decodeERC721AssetData(bytes memory assetData)
+ internal
+ pure
+ returns (
+ address token,
+ uint256 tokenId,
+ bytes memory receiverData
+ )
+ {
+ // Decode asset data.
+ token = readAddress(assetData, 0);
+ tokenId = readUint256(assetData, 20);
+ if (assetData.length > 52) {
+ receiverData = readBytes(assetData, 52);
+ }
+
+ return (
+ token,
+ tokenId,
+ receiverData
+ );
+ }
+}
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibAssetProxyErrors.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibAssetProxyErrors.sol
index 65bdacdb7..dca4f400f 100644
--- a/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibAssetProxyErrors.sol
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibAssetProxyErrors.sol
@@ -25,8 +25,4 @@ contract LibAssetProxyErrors {
string constant TARGET_ALREADY_AUTHORIZED = "TARGET_ALREADY_AUTHORIZED"; // Target address must not already be authorized.
string constant INDEX_OUT_OF_BOUNDS = "INDEX_OUT_OF_BOUNDS"; // Specified array index is out of bounds.
string constant AUTHORIZED_ADDRESS_MISMATCH = "AUTHORIZED_ADDRESS_MISMATCH"; // Address at index does not match given target address.
-
- /// AssetProxy errors ///
- string constant INVALID_AMOUNT = "INVALID_AMOUNT"; // Transfer amount must equal 1.
- string constant TRANSFER_FAILED = "TRANSFER_FAILED"; // Transfer failed.
}
diff --git a/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibTransferErrors.sol b/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibTransferErrors.sol
new file mode 100644
index 000000000..ba784ab22
--- /dev/null
+++ b/packages/contracts/src/contracts/current/protocol/AssetProxy/libs/LibTransferErrors.sol
@@ -0,0 +1,25 @@
+/*
+
+ 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 LibTransferErrors {
+ /// Transfer errors ///
+ string constant INVALID_AMOUNT = "INVALID_AMOUNT"; // Transfer amount must equal 1.
+ string constant TRANSFER_FAILED = "TRANSFER_FAILED"; // Transfer failed.
+}
diff --git a/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol b/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol
index 6afb9973a..97fb5fb0f 100644
--- a/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol
+++ b/packages/contracts/src/contracts/current/utils/LibMem/LibMem.sol
@@ -80,9 +80,6 @@ contract LibMem
//
if (source > dest) {
assembly {
- // Record the total number of full words to copy
- let nWords := div(length, 32)
-
// 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
@@ -98,20 +95,19 @@ contract LibMem
let last := mload(sEnd)
// Copy whole words front to back
- for {let i := 0} lt(i, nWords) {i := add(i, 1)} {
+ // 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 {
- // Record the total number of full words to copy
- let nWords := div(length, 32)
-
// We subtract 32 from `sEnd` and `dEnd` because those
// are the starting points when copying a word at the end.
length := sub(length, 32)
@@ -125,12 +121,18 @@ contract LibMem
let first := mload(source)
// Copy whole words back to front
- for {let i := 0} lt(i, nWords) {i := add(i, 1)} {
+ // 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)
}