Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2019 from jalextowle/feature/contracts/3.0/disall…
Browse files Browse the repository at this point in the history
…ow-address-zero

Disallow Zero address in MixinAuthorizable and Ownable
  • Loading branch information
abandeali1 authored Aug 6, 2019
2 parents abe72b7 + 3915c7e commit 2f91a12
Show file tree
Hide file tree
Showing 28 changed files with 737 additions and 72 deletions.
9 changes: 9 additions & 0 deletions contracts/asset-proxy/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
[
{
"version": "3.2.0",
"changes": [
{
"note": "Disallow the zero address from being made an authorized address in MixinAuthorizable, and created an archive directory that includes an old version of Ownable",
"pr": 2019
}
]
},
{
"timestamp": 1563193019,
"version": "2.2.2",
Expand Down
2 changes: 1 addition & 1 deletion contracts/asset-proxy/compiler.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
}
},
"contracts": [
"archive/MixinAuthorizable.sol",
"src/ERC1155Proxy.sol",
"src/ERC20Proxy.sol",
"src/ERC721Proxy.sol",
"src/MixinAuthorizable.sol",
"src/MultiAssetProxy.sol",
"src/StaticCallProxy.sol",
"src/interfaces/IAssetData.sol",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
Expand All @@ -18,9 +18,9 @@

pragma solidity ^0.5.9;

import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "./interfaces/IAssetProxy.sol";
import "./interfaces/IAssetProxyDispatcher.sol";
import "../archive/Ownable.sol";
import "../src/interfaces/IAssetProxy.sol";
import "../src/interfaces/IAssetProxyDispatcher.sol";


contract MixinAssetProxyDispatcher is
Expand Down Expand Up @@ -84,7 +84,7 @@ contract MixinAssetProxyDispatcher is
assetData.length > 3,
"LENGTH_GREATER_THAN_3_REQUIRED"
);

// Lookup assetProxy. We do not use `LibBytes.readBytes4` for gas efficiency reasons.
bytes4 assetProxyId;
assembly {
Expand All @@ -100,10 +100,10 @@ contract MixinAssetProxyDispatcher is
assetProxy != address(0),
"ASSET_PROXY_DOES_NOT_EXIST"
);

// We construct calldata for the `assetProxy.transferFrom` ABI.
// The layout of this calldata is in the table below.
//
//
// | Area | Offset | Length | Contents |
// | -------- |--------|---------|-------------------------------------------- |
// | Header | 0 | 4 | function selector |
Expand All @@ -127,12 +127,12 @@ contract MixinAssetProxyDispatcher is
// `cdEnd` is the end of the calldata for `assetProxy.transferFrom`.
let cdEnd := add(cdStart, add(132, dataAreaLength))


/////// Setup Header Area ///////
// This area holds the 4-byte `transferFromSelector`.
// bytes4(keccak256("transferFrom(bytes,address,address,uint256)")) = 0xa85e59e4
mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000)

/////// Setup Params Area ///////
// Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes.
// Notes:
Expand All @@ -142,7 +142,7 @@ contract MixinAssetProxyDispatcher is
mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(cdStart, 100), amount)

/////// Setup Data Area ///////
// This area holds `assetData`.
let dataArea := add(cdStart, 132)
Expand All @@ -159,7 +159,7 @@ contract MixinAssetProxyDispatcher is
assetProxy, // call address of asset proxy
0, // don't send any ETH
cdStart, // pointer to start of input
sub(cdEnd, cdStart), // length of input
sub(cdEnd, cdStart), // length of input
cdStart, // write output over input
512 // reserve 512 bytes for output
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
Expand All @@ -18,8 +18,8 @@

pragma solidity ^0.5.9;

import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "./interfaces/IAuthorizable.sol";
import "../archive/Ownable.sol";
import "../src/interfaces/IAuthorizable.sol";


contract MixinAuthorizable is
Expand Down
33 changes: 33 additions & 0 deletions contracts/asset-proxy/contracts/archive/Ownable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
pragma solidity ^0.5.9;

import "@0x/contracts-utils/contracts/src/interfaces/IOwnable.sol";


contract Ownable is
IOwnable
{
address public owner;

constructor ()
public
{
owner = msg.sender;
}

modifier onlyOwner() {
require(
msg.sender == owner,
"ONLY_CONTRACT_OWNER"
);
_;
}

function transferOwnership(address newOwner)
public
onlyOwner
{
if (newOwner != address(0)) {
owner = newOwner;
}
}
}
4 changes: 2 additions & 2 deletions contracts/asset-proxy/contracts/src/ERC1155Proxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/SafeMath.sol";
import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
import "./MixinAuthorizable.sol";
import "../archive/MixinAuthorizable.sol";
import "./interfaces/IAssetProxy.sol";


Expand Down Expand Up @@ -69,7 +69,7 @@ contract ERC1155Proxy is
for (uint256 i = 0; i != length; i++) {
// We write the scaled values to an unused location in memory in order
// to avoid copying over `ids` or `data`. This is possible if they are
// identical to `values` and the offsets for each are pointing to the
// identical to `values` and the offsets for each are pointing to the
// same location in the ABI encoded calldata.
scaledValues[i] = _safeMul(values[i], amount);
}
Expand Down
14 changes: 7 additions & 7 deletions contracts/asset-proxy/contracts/src/ERC20Proxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@

pragma solidity ^0.5.9;

import "./MixinAuthorizable.sol";
import "../archive/MixinAuthorizable.sol";


contract ERC20Proxy is
MixinAuthorizable
{
// Id of this proxy.
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC20Token(address)"));

// solhint-disable-next-line payable-fallback
function ()
function ()
external
{
assembly {
Expand Down Expand Up @@ -117,13 +117,13 @@ contract ERC20Proxy is
// * The "token address" is offset 32+4=36 bytes into "assetData" (tables 1 & 2).
// [tokenOffset = assetDataOffsetFromHeader + 36 = calldataload(4) + 4 + 36]
let token := calldataload(add(calldataload(4), 40))

/////// Setup Header Area ///////
// This area holds the 4-byte `transferFrom` selector.
// Any trailing data in transferFromSelector will be
// overwritten in the next `mstore` call.
mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000)

/////// Setup Params Area ///////
// We copy the fields `from`, `to` and `amount` in bulk
// from our own calldata to the new calldata.
Expand All @@ -147,7 +147,7 @@ contract ERC20Proxy is
// If the token does return data, we require that it is a single
// nonzero 32 bytes value.
// So the transfer succeeded if the call succeeded and either
// returned nothing, or returned a non-zero 32 byte value.
// returned nothing, or returned a non-zero 32 byte value.
success := and(success, or(
iszero(returndatasize),
and(
Expand All @@ -158,7 +158,7 @@ contract ERC20Proxy is
if success {
return(0, 0)
}

// Revert with `Error("TRANSFER_FAILED")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
Expand Down
12 changes: 6 additions & 6 deletions contracts/asset-proxy/contracts/src/ERC721Proxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

pragma solidity ^0.5.9;

import "./MixinAuthorizable.sol";
import "../archive/MixinAuthorizable.sol";


contract ERC721Proxy is
Expand All @@ -28,7 +28,7 @@ contract ERC721Proxy is
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256)"));

// solhint-disable-next-line payable-fallback
function ()
function ()
external
{
assembly {
Expand Down Expand Up @@ -93,10 +93,10 @@ contract ERC721Proxy is
// | Params | | 2 * 32 | function parameters: |
// | | 4 | 12 + 20 | 1. token address |
// | | 36 | | 2. tokenId |

// We construct calldata for the `token.transferFrom` ABI.
// The layout of this calldata is in the table below.
//
//
// | Area | Offset | Length | Contents |
// |----------|--------|---------|-------------------------------------|
// | Header | 0 | 4 | function selector |
Expand All @@ -121,7 +121,7 @@ contract ERC721Proxy is
// Any trailing data in transferFromSelector will be
// overwritten in the next `mstore` call.
mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000)

/////// Setup Params Area ///////
// We copy the fields `from` and `to` in bulk
// from our own calldata to the new calldata.
Expand All @@ -145,7 +145,7 @@ contract ERC721Proxy is
if success {
return(0, 0)
}

// Revert with `Error("TRANSFER_FAILED")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
Expand Down
28 changes: 14 additions & 14 deletions contracts/asset-proxy/contracts/src/MultiAssetProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

pragma solidity ^0.5.9;

import "./MixinAssetProxyDispatcher.sol";
import "./MixinAuthorizable.sol";
import "../archive/MixinAssetProxyDispatcher.sol";
import "../archive/MixinAuthorizable.sol";


contract MultiAssetProxy is
Expand Down Expand Up @@ -105,7 +105,7 @@ contract MultiAssetProxy is
// | | 36 | | 2. offset to nestedAssetData (*) |
// | Data | | | amounts: |
// | | 68 | 32 | amounts Length |
// | | 100 | a | amounts Contents |
// | | 100 | a | amounts Contents |
// | | | | nestedAssetData: |
// | | 100 + a | 32 | nestedAssetData Length |
// | | 132 + a | b | nestedAssetData Contents (offsets) |
Expand Down Expand Up @@ -149,8 +149,8 @@ contract MultiAssetProxy is
// + 32 (amounts offset)
let nestedAssetDataOffset := calldataload(add(assetDataOffset, 68))

// In order to find the start of the `amounts` contents, we must add:
// assetDataOffset
// In order to find the start of the `amounts` contents, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (assetProxyId)
// + amountsOffset
Expand All @@ -160,8 +160,8 @@ contract MultiAssetProxy is
// Load number of elements in `amounts`
let amountsLen := calldataload(sub(amountsContentsStart, 32))

// In order to find the start of the `nestedAssetData` contents, we must add:
// assetDataOffset
// In order to find the start of the `nestedAssetData` contents, we must add:
// assetDataOffset
// + 32 (assetData len)
// + 4 (assetProxyId)
// + nestedAssetDataOffset
Expand Down Expand Up @@ -190,10 +190,10 @@ contract MultiAssetProxy is

// Overwrite existing offset to `assetData` with our own
mstore(4, 128)

// Load `amount`
let amount := calldataload(100)

// Calculate number of bytes in `amounts` contents
let amountsByteLen := mul(amountsLen, 32)

Expand All @@ -208,7 +208,7 @@ contract MultiAssetProxy is
let amountsElement := calldataload(add(amountsContentsStart, i))
let totalAmount := mul(amountsElement, amount)

// Revert if `amount` != 0 and multiplication resulted in an overflow
// Revert if `amount` != 0 and multiplication resulted in an overflow
if iszero(or(
iszero(amount),
eq(div(totalAmount, amount), amountsElement)
Expand All @@ -228,7 +228,7 @@ contract MultiAssetProxy is
let nestedAssetDataElementOffset := calldataload(add(nestedAssetDataContentsStart, i))

// In order to find the start of the `nestedAssetData[i]` contents, we must add:
// assetDataOffset
// assetDataOffset
// + 32 (assetData len)
// + 4 (assetProxyId)
// + nestedAssetDataOffset
Expand Down Expand Up @@ -274,7 +274,7 @@ contract MultiAssetProxy is
mstore(164, assetProxies_slot)
assetProxy := sload(keccak256(132, 64))
}

// Revert if AssetProxy with given id does not exist
if iszero(assetProxy) {
// Revert with `Error("ASSET_PROXY_DOES_NOT_EXIST")`
Expand All @@ -284,7 +284,7 @@ contract MultiAssetProxy is
mstore(96, 0)
revert(0, 100)
}

// Copy `nestedAssetData[i]` from calldata to memory
calldatacopy(
132, // memory slot after `amounts[i]`
Expand All @@ -298,7 +298,7 @@ contract MultiAssetProxy is
assetProxy, // call address of asset proxy
0, // don't send any ETH
0, // pointer to start of input
add(164, nestedAssetDataElementLen), // length of input
add(164, nestedAssetDataElementLen), // length of input
0, // write output over memory that won't be reused
0 // don't copy output to memory
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Copyright 2018 ZeroEx Intl.
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.
Expand Down Expand Up @@ -54,7 +54,7 @@ contract IAuthorizable is
uint256 index
)
external;

/// @dev Gets all authorized addresses.
/// @return Array of authorized addresses.
function getAuthorizedAddresses()
Expand Down
Loading

0 comments on commit 2f91a12

Please sign in to comment.