Remove LibAssetProxyIds and TestLibConstants

This commit is contained in:
Amir Bandeali 2019-07-10 09:15:40 -07:00
parent 7d5276ad11
commit 2e97cfa5e5
10 changed files with 48 additions and 220 deletions

View File

@ -1,40 +0,0 @@
/*
Copyright 2019 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.5.5;
contract LibAssetProxyIds {
// AssetProxy Ids are equiavalent the first 4 bytes of the keccak256 hash of the function signature assigned to each AssetProxy.
// ERC20Token(address)
bytes4 constant public ERC20_PROXY_ID = 0xf47261b0;
// ERC721Token(address,uint256)
bytes4 constant public ERC721_PROXY_ID = 0x02571792;
// ERC1155Assets(address,uint256[],uint256[],bytes)
bytes4 constant public ERC1155_PROXY_ID = 0xa7cb5fb7;
// MultiAsset(uint256[],bytes[])
bytes4 constant public MULTI_ASSET_PROXY_ID = 0x94cfcdd7;
// StaticCall(address,bytes,bytes32)
bytes4 constant public STATIC_CALL_PROXY_ID = 0xc339d10a;
}

View File

@ -20,32 +20,19 @@ pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-asset-proxy/contracts/src/libs/LibAssetProxyIds.sol";
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetData.sol";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetProxy.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc721/contracts/src/interfaces/IERC721Token.sol";
import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
contract LibAssetData is
LibAssetProxyIds
{
contract LibAssetData {
// 2^256 - 1
uint256 constant internal _MAX_UINT256 = uint256(-1);
// ERC20 selectors
bytes4 constant internal _ERC20_BALANCE_OF_SELECTOR = 0x70a08231;
bytes4 constant internal _ERC20_ALLOWANCE_SELECTOR = 0xdd62ed3e;
// ERC721 selectors
bytes4 constant internal _ERC721_OWNER_OF_SELECTOR = 0x6352211e;
bytes4 constant internal _ERC721_IS_APPROVED_FOR_ALL_SELECTOR = 0xe985e9c5;
bytes4 constant internal _ERC721_GET_APPROVED_SELECTOR = 0x081812fc;
// ERC1155 selectors
bytes4 constant internal _ERC1155_BALANCE_OF_SELECTOR = 0x00fdd58e;
bytes4 constant internal _ERC1155_IS_APPROVED_FOR_ALL_SELECTOR = 0xe985e9c5;
// `transferFrom` selector for all AssetProxy contracts
bytes4 constant internal _ASSET_PROXY_TRANSFER_FROM_SELECTOR = 0xa85e59e4;
using LibBytes for bytes;
// solhint-disable var-name-mixedcase
@ -60,10 +47,10 @@ contract LibAssetData is
public
{
_EXCHANGE = IExchange(_exchange);
_ERC20_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC20_PROXY_ID);
_ERC721_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC721_PROXY_ID);
_ERC1155_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(ERC1155_PROXY_ID);
_STATIC_CALL_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(STATIC_CALL_PROXY_ID);
_ERC20_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).ERC20Token.selector);
_ERC721_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).ERC721Token.selector);
_ERC1155_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).ERC1155Assets.selector);
_STATIC_CALL_PROXY_ADDRESS = _EXCHANGE.getAssetProxy(IAssetData(address(0)).StaticCall.selector);
}
/// @dev Returns the owner's balance of the assets(s) specified in
@ -81,23 +68,33 @@ contract LibAssetData is
// Get id of AssetProxy contract
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == ERC20_PROXY_ID) {
if (assetProxyId == IAssetData(address(0)).ERC20Token.selector) {
// Get ERC20 token address
address tokenAddress = assetData.readAddress(16);
// Encode data for `balanceOf(ownerAddress)`
bytes memory balanceOfData = abi.encodeWithSelector(_ERC20_BALANCE_OF_SELECTOR, ownerAddress);
bytes memory balanceOfData = abi.encodeWithSelector(
IERC20Token(address(0)).balanceOf.selector,
ownerAddress
);
// Query balance
(bool success, bytes memory returnData) = tokenAddress.staticcall(balanceOfData);
balance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
} else if (assetProxyId == ERC721_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) {
// Get ERC721 token address and id
(, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData);
// Check if id is owned by ownerAddress
balance = getERC721TokenOwner(tokenAddress, tokenId) == ownerAddress ? 1 : 0;
} else if (assetProxyId == ERC1155_PROXY_ID) {
bytes memory ownerOfCalldata = abi.encodeWithSelector(
IERC721Token(address(0)).ownerOf.selector,
tokenId
);
(bool success, bytes memory returnData) = tokenAddress.staticcall(ownerOfCalldata);
address currentOwnerAddress = (success && returnData.length == 32) ? returnData.readAddress(12) : address(0);
balance = currentOwnerAddress == ownerAddress ? 1 : 0;
} else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) {
// Get ERC1155 token address, array of ids, and array of values
(, address tokenAddress, uint256[] memory tokenIds, uint256[] memory tokenValues,) = decodeERC1155AssetData(assetData);
@ -105,7 +102,7 @@ contract LibAssetData is
for (uint256 i = 0; i != length; i++) {
// Encode data for `balanceOf(ownerAddress, tokenIds[i])
bytes memory balanceOfData = abi.encodeWithSelector(
_ERC1155_BALANCE_OF_SELECTOR,
IERC1155(address(0)).balanceOf.selector,
ownerAddress,
tokenIds[i]
);
@ -120,10 +117,10 @@ contract LibAssetData is
balance = scaledBalance;
}
}
} else if (assetProxyId == STATIC_CALL_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) {
// Encode data for `staticCallProxy.transferFrom(assetData,...)`
bytes memory transferFromData = abi.encodeWithSelector(
_ASSET_PROXY_TRANSFER_FROM_SELECTOR,
IAssetProxy(address(0)).transferFrom.selector,
assetData,
address(0), // `from` address is not used
address(0), // `to` address is not used
@ -135,7 +132,7 @@ contract LibAssetData is
// Success means that the staticcall can be made an unlimited amount of times
balance = success ? _MAX_UINT256 : 0;
} else if (assetProxyId == MULTI_ASSET_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).MultiAsset.selector) {
// Get array of values and array of assetDatas
(, uint256[] memory assetAmounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
@ -190,7 +187,7 @@ contract LibAssetData is
// Get id of AssetProxy contract
bytes4 assetProxyId = assetData.readBytes4(0);
if (assetProxyId == MULTI_ASSET_PROXY_ID) {
if (assetProxyId == IAssetData(address(0)).MultiAsset.selector) {
// Get array of values and array of assetDatas
(, uint256[] memory amounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
@ -208,13 +205,13 @@ contract LibAssetData is
return allowance;
}
if (assetProxyId == ERC20_PROXY_ID) {
if (assetProxyId == IAssetData(address(0)).ERC20Token.selector) {
// Get ERC20 token address
address tokenAddress = assetData.readAddress(16);
// Encode data for `allowance(ownerAddress, _ERC20_PROXY_ADDRESS)`
bytes memory allowanceData = abi.encodeWithSelector(
_ERC20_ALLOWANCE_SELECTOR,
IERC20Token(address(0)).allowance.selector,
ownerAddress,
_ERC20_PROXY_ADDRESS
);
@ -222,13 +219,13 @@ contract LibAssetData is
// Query allowance
(bool success, bytes memory returnData) = tokenAddress.staticcall(allowanceData);
allowance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
} else if (assetProxyId == ERC721_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) {
// Get ERC721 token address and id
(, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData);
// Encode data for `isApprovedForAll(ownerAddress, _ERC721_PROXY_ADDRESS)`
bytes memory isApprovedForAllData = abi.encodeWithSelector(
_ERC721_IS_APPROVED_FOR_ALL_SELECTOR,
IERC721Token(address(0)).isApprovedForAll.selector,
ownerAddress,
_ERC721_PROXY_ADDRESS
);
@ -238,7 +235,7 @@ contract LibAssetData is
// If not approved for all, call `getApproved(tokenId)`
if (!success || returnData.length != 32 || returnData.readUint256(0) != 1) {
// Encode data for `getApproved(tokenId)`
bytes memory getApprovedData = abi.encodeWithSelector(_ERC721_GET_APPROVED_SELECTOR, tokenId);
bytes memory getApprovedData = abi.encodeWithSelector(IERC721Token(address(0)).getApproved.selector, tokenId);
(success, returnData) = tokenAddress.staticcall(getApprovedData);
// Allowance is 1 if successful and the approved address is the ERC721Proxy
@ -247,13 +244,13 @@ contract LibAssetData is
// Allowance is 2^256 - 1 if `isApprovedForAll` returned true
allowance = _MAX_UINT256;
}
} else if (assetProxyId == ERC1155_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) {
// Get ERC1155 token address
(, address tokenAddress, , , ) = decodeERC1155AssetData(assetData);
// Encode data for `isApprovedForAll(ownerAddress, _ERC1155_PROXY_ADDRESS)`
bytes memory isApprovedForAllData = abi.encodeWithSelector(
_ERC1155_IS_APPROVED_FOR_ALL_SELECTOR,
IERC1155(address(0)).isApprovedForAll.selector,
ownerAddress,
_ERC1155_PROXY_ADDRESS
);
@ -261,7 +258,7 @@ contract LibAssetData is
// Query allowance
(bool success, bytes memory returnData) = tokenAddress.staticcall(isApprovedForAllData);
allowance = success && returnData.length == 32 && returnData.readUint256(0) == 1 ? _MAX_UINT256 : 0;
} else if (assetProxyId == STATIC_CALL_PROXY_ID) {
} else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) {
// The StaticCallProxy does not require any approvals
allowance = _MAX_UINT256;
}
@ -327,7 +324,7 @@ contract LibAssetData is
pure
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(ERC20_PROXY_ID, tokenAddress);
assetData = abi.encodeWithSelector(IAssetData(address(0)).ERC20Token.selector, tokenAddress);
return assetData;
}
@ -346,7 +343,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC20_PROXY_ID,
assetProxyId == IAssetData(address(0)).ERC20Token.selector,
"WRONG_PROXY_ID"
);
@ -364,7 +361,7 @@ contract LibAssetData is
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
ERC721_PROXY_ID,
IAssetData(address(0)).ERC721Token.selector,
tokenAddress,
tokenId
);
@ -388,7 +385,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC721_PROXY_ID,
assetProxyId == IAssetData(address(0)).ERC721Token.selector,
"WRONG_PROXY_ID"
);
@ -414,7 +411,7 @@ contract LibAssetData is
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
ERC1155_PROXY_ID,
IAssetData(address(0)).ERC1155Assets.selector,
tokenAddress,
tokenIds,
tokenValues,
@ -446,7 +443,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == ERC1155_PROXY_ID,
assetProxyId == IAssetData(address(0)).ERC1155Assets.selector,
"WRONG_PROXY_ID"
);
@ -482,7 +479,7 @@ contract LibAssetData is
returns (bytes memory assetData)
{
assetData = abi.encodeWithSelector(
MULTI_ASSET_PROXY_ID,
IAssetData(address(0)).MultiAsset.selector,
amounts,
nestedAssetData
);
@ -507,7 +504,7 @@ contract LibAssetData is
assetProxyId = assetData.readBytes4(0);
require(
assetProxyId == MULTI_ASSET_PROXY_ID,
assetProxyId == IAssetData(address(0)).MultiAsset.selector,
"WRONG_PROXY_ID"
);
@ -518,24 +515,4 @@ contract LibAssetData is
);
// solhint-enable indent
}
/// @dev Calls `asset.ownerOf(tokenId)`, but returns a null owner instead of reverting on an unowned asset.
/// @param tokenAddress Address of ERC721 asset.
/// @param tokenId The identifier for the specific NFT.
/// @return Owner of tokenId or null address if unowned.
function getERC721TokenOwner(address tokenAddress, uint256 tokenId)
public
view
returns (address ownerAddress)
{
bytes memory ownerOfCalldata = abi.encodeWithSelector(
_ERC721_OWNER_OF_SELECTOR,
tokenId
);
(bool success, bytes memory returnData) = tokenAddress.staticcall(ownerOfCalldata);
ownerAddress = (success && returnData.length == 32) ? returnData.readAddress(12) : address(0);
return ownerAddress;
}
}

View File

@ -465,20 +465,6 @@ describe('LibAssetData', () => {
});
});
describe('getERC721TokenOwner', async () => {
it('should return the null address when tokenId is not owned', async () => {
const nonexistentTokenId = new BigNumber(1234567890);
expect(
await libAssetData.getERC721TokenOwner.callAsync(erc721Token.address, nonexistentTokenId),
).to.be.equal(constants.NULL_ADDRESS);
});
it('should return the owner address when tokenId is owned', async () => {
expect(
await libAssetData.getERC721TokenOwner.callAsync(erc721Token.address, firstERC721TokenId),
).to.be.equal(tokenOwnerAddress);
});
});
describe('getBalanceAndAllowance', () => {
it('should query balance and allowance together, from asset data', async () => {
const allowance = new BigNumber(1);

View File

@ -34,7 +34,6 @@
"src/SafeMath.sol",
"src/interfaces/IAuthorizable.sol",
"src/interfaces/IOwnable.sol",
"test/TestConstants.sol",
"test/TestLibAddress.sol",
"test/TestLibAddressArray.sol",
"test/TestLibBytes.sol",

View File

@ -1,57 +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.5.5;
import "../src/LibBytes.sol";
// solhint-disable max-line-length
contract TestConstants {
using LibBytes for bytes;
bytes4 constant internal ERC20_PROXY_ID = bytes4(keccak256("ERC20Token(address)"));
address constant internal KOVAN_ZRX_ADDRESS = 0x6Ff6C0Ff1d68b964901F986d4C9FA3ac68346570;
bytes constant internal KOVAN_ZRX_ASSET_DATA = "\xf4\x72\x61\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\xf6\xc0\xff\x1d\x68\xb9\x64\x90\x1f\x98\x6d\x4c\x9f\xa3\xac\x68\x34\x65\x70";
address constant internal MAINNET_ZRX_ADDRESS = 0xE41d2489571d322189246DaFA5ebDe1F4699F498;
bytes constant public MAINNET_ZRX_ASSET_DATA = "\xf4\x72\x61\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x1d\x24\x89\x57\x1d\x32\x21\x89\x24\x6d\xaf\xa5\xeb\xde\x1f\x46\x99\xf4\x98";
function assertValidZrxAssetData()
public
pure
returns (bool)
{
bytes memory kovanZrxAssetData = abi.encodeWithSelector(ERC20_PROXY_ID, KOVAN_ZRX_ADDRESS);
require(
kovanZrxAssetData.equals(KOVAN_ZRX_ASSET_DATA),
"INVALID_KOVAN_ZRX_ASSET_DATA"
);
bytes memory mainetZrxAssetData = abi.encodeWithSelector(ERC20_PROXY_ID, MAINNET_ZRX_ADDRESS);
require(
mainetZrxAssetData.equals(MAINNET_ZRX_ASSET_DATA),
"INVALID_MAINNET_ZRX_ASSET_DATA"
);
return true;
}
}
// solhint-enable max-line-length

View File

@ -34,7 +34,7 @@
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
},
"config": {
"abis": "./generated-artifacts/@(Authorizable|IAuthorizable|IOwnable|LibAddress|LibBytes|LibEIP1271|LibEIP712|Ownable|ReentrancyGuard|SafeMath|TestConstants|TestLibAddress|TestLibAddressArray|TestLibBytes|TestLibEIP712|TestLibRichErrors|TestOwnable|TestReentrancyGuard|TestSafeMath).json",
"abis": "./generated-artifacts/@(Authorizable|IAuthorizable|IOwnable|LibAddress|LibBytes|LibEIP1271|LibEIP712|Ownable|ReentrancyGuard|SafeMath|TestLibAddress|TestLibAddressArray|TestLibBytes|TestLibEIP712|TestLibRichErrors|TestOwnable|TestReentrancyGuard|TestSafeMath).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {

View File

@ -15,7 +15,6 @@ import * as LibEIP712 from '../generated-artifacts/LibEIP712.json';
import * as Ownable from '../generated-artifacts/Ownable.json';
import * as ReentrancyGuard from '../generated-artifacts/ReentrancyGuard.json';
import * as SafeMath from '../generated-artifacts/SafeMath.json';
import * as TestConstants from '../generated-artifacts/TestConstants.json';
import * as TestLibAddress from '../generated-artifacts/TestLibAddress.json';
import * as TestLibAddressArray from '../generated-artifacts/TestLibAddressArray.json';
import * as TestLibBytes from '../generated-artifacts/TestLibBytes.json';
@ -35,7 +34,6 @@ export const artifacts = {
SafeMath: SafeMath as ContractArtifact,
IAuthorizable: IAuthorizable as ContractArtifact,
IOwnable: IOwnable as ContractArtifact,
TestConstants: TestConstants as ContractArtifact,
TestLibAddress: TestLibAddress as ContractArtifact,
TestLibAddressArray: TestLibAddressArray as ContractArtifact,
TestLibBytes: TestLibBytes as ContractArtifact,

View File

@ -13,7 +13,6 @@ export * from '../generated-wrappers/lib_e_i_p712';
export * from '../generated-wrappers/ownable';
export * from '../generated-wrappers/reentrancy_guard';
export * from '../generated-wrappers/safe_math';
export * from '../generated-wrappers/test_constants';
export * from '../generated-wrappers/test_lib_address';
export * from '../generated-wrappers/test_lib_address_array';
export * from '../generated-wrappers/test_lib_bytes';

View File

@ -1,33 +0,0 @@
import { chaiSetup, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import * as chai from 'chai';
import { artifacts, TestConstantsContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('Libs', () => {
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('LibConstants', () => {
describe('ZRX_ASSET_DATA', () => {
it('should have the correct ZRX_ASSET_DATA', async () => {
const testConstants = await TestConstantsContract.deployFrom0xArtifactAsync(
artifacts.TestConstants,
provider,
txDefaults,
);
const isValid = await testConstants.assertValidZrxAssetData.callAsync();
expect(isValid).to.be.equal(true);
});
});
});
});

View File

@ -13,7 +13,6 @@
"generated-artifacts/Ownable.json",
"generated-artifacts/ReentrancyGuard.json",
"generated-artifacts/SafeMath.json",
"generated-artifacts/TestConstants.json",
"generated-artifacts/TestLibAddress.json",
"generated-artifacts/TestLibAddressArray.json",
"generated-artifacts/TestLibBytes.json",