Update contracts with revert reasons and constructor keyword
This commit is contained in:
@@ -16,12 +16,14 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../utils/Authorizable/IAuthorizable.sol";
|
||||
|
||||
contract IAssetProxy is IAuthorizable {
|
||||
contract IAssetProxy is
|
||||
IAuthorizable
|
||||
{
|
||||
|
||||
/// @dev Transfers assets. Either succeeds or throws.
|
||||
/// @param assetMetadata Byte array encoded for the respective asset proxy.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./mixins/MAssetProxy.sol";
|
||||
@@ -25,8 +25,8 @@ import "../../utils/Authorizable/Authorizable.sol";
|
||||
|
||||
contract MixinAssetProxy is
|
||||
IAssetProxy,
|
||||
MAssetProxy,
|
||||
Authorizable
|
||||
Authorizable,
|
||||
MAssetProxy
|
||||
{
|
||||
|
||||
/// @dev Transfers assets. Either succeeds or throws.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract MAssetProxy {
|
||||
|
@@ -16,10 +16,9 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
import "../../../utils/LibBytes/LibBytes.sol";
|
||||
import "../../../tokens/ERC20Token/IERC20Token.sol";
|
||||
import "../MixinAssetProxy.sol";
|
||||
@@ -29,8 +28,14 @@ contract ERC20Proxy is
|
||||
MixinAssetProxy
|
||||
{
|
||||
|
||||
// Id of this proxy.
|
||||
uint8 constant PROXY_ID = 1;
|
||||
|
||||
// Revert reasons
|
||||
string constant INVALID_METADATA_LENGTH = "Metadata must have a length of 21.";
|
||||
string constant TRANSFER_FAILED = "Transfer failed.";
|
||||
string constant PROXY_ID_MISMATCH = "Proxy id in metadata does not match this proxy id.";
|
||||
|
||||
/// @dev Internal version of `transferFrom`.
|
||||
/// @param assetMetadata Encoded byte array.
|
||||
/// @param from Address to transfer asset from.
|
||||
@@ -44,15 +49,24 @@ contract ERC20Proxy is
|
||||
internal
|
||||
{
|
||||
// Data must be intended for this proxy.
|
||||
require(uint8(assetMetadata[0]) == PROXY_ID);
|
||||
require(
|
||||
uint8(assetMetadata[0]) == PROXY_ID,
|
||||
PROXY_ID_MISMATCH
|
||||
);
|
||||
|
||||
// Decode metadata.
|
||||
require(assetMetadata.length == 21);
|
||||
require(
|
||||
assetMetadata.length == 21,
|
||||
INVALID_METADATA_LENGTH
|
||||
);
|
||||
address token = readAddress(assetMetadata, 1);
|
||||
|
||||
// Transfer tokens.
|
||||
bool success = IERC20Token(token).transferFrom(from, to, amount);
|
||||
require(success == true);
|
||||
require(
|
||||
success == true,
|
||||
TRANSFER_FAILED
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Gets the proxy id associated with the proxy address.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../../utils/LibBytes/LibBytes.sol";
|
||||
@@ -28,8 +28,14 @@ contract ERC721Proxy is
|
||||
MixinAssetProxy
|
||||
{
|
||||
|
||||
// Id of this proxy.
|
||||
uint8 constant PROXY_ID = 2;
|
||||
|
||||
// Revert reasons
|
||||
string constant INVALID_TRANSFER_AMOUNT = "Transfer amount must equal 1.";
|
||||
string constant INVALID_METADATA_LENGTH = "Metadata must have a length of 53.";
|
||||
string constant PROXY_ID_MISMATCH = "Proxy id in metadata does not match this proxy id.";
|
||||
|
||||
/// @dev Internal version of `transferFrom`.
|
||||
/// @param assetMetadata Encoded byte array.
|
||||
/// @param from Address to transfer asset from.
|
||||
@@ -43,13 +49,22 @@ contract ERC721Proxy is
|
||||
internal
|
||||
{
|
||||
// Data must be intended for this proxy.
|
||||
require(uint8(assetMetadata[0]) == PROXY_ID);
|
||||
require(
|
||||
uint8(assetMetadata[0]) == PROXY_ID,
|
||||
PROXY_ID_MISMATCH
|
||||
);
|
||||
|
||||
// There exists only 1 of each token.
|
||||
require(amount == 1);
|
||||
require(
|
||||
amount == 1,
|
||||
INVALID_TRANSFER_AMOUNT
|
||||
);
|
||||
|
||||
// Decode metadata.
|
||||
require(assetMetadata.length == 53);
|
||||
// Decode metadata
|
||||
require(
|
||||
assetMetadata.length == 53,
|
||||
INVALID_METADATA_LENGTH
|
||||
);
|
||||
address token = readAddress(assetMetadata, 1);
|
||||
uint256 tokenId = readUint256(assetMetadata, 21);
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./MixinExchangeCore.sol";
|
||||
@@ -36,7 +36,7 @@ contract Exchange is
|
||||
{
|
||||
string constant public VERSION = "2.0.1-alpha";
|
||||
|
||||
function Exchange(bytes memory _zrxProxyData)
|
||||
constructor (bytes memory _zrxProxyData)
|
||||
public
|
||||
MixinExchangeCore()
|
||||
MixinSignatureValidator()
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract ISigner {
|
||||
|
@@ -1,35 +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.21;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract LibErrors {
|
||||
|
||||
// Error Codes
|
||||
enum Errors {
|
||||
ORDER_EXPIRED, // Order has already expired
|
||||
ORDER_FULLY_FILLED, // Order has already been fully filled
|
||||
ORDER_CANCELLED, // Order has already been cancelled
|
||||
ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
|
||||
INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer
|
||||
}
|
||||
|
||||
event ExchangeError(uint8 indexed errorId, bytes32 indexed orderHash);
|
||||
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
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.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract LibExchangeErrors {
|
||||
|
||||
// Error Codes
|
||||
enum Errors {
|
||||
ORDER_EXPIRED, // Order has already expired
|
||||
ORDER_FULLY_FILLED, // Order has already been fully filled
|
||||
ORDER_CANCELLED, // Order has already been cancelled
|
||||
ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
|
||||
INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer
|
||||
}
|
||||
|
||||
event ExchangeError(uint8 indexed errorId, bytes32 indexed orderHash);
|
||||
|
||||
// Core revert reasons
|
||||
string constant GREATER_THAN_ZERO_AMOUNT_REQUIRED = "Amount must be greater than 0.";
|
||||
string constant SIGNATURE_VALIDATION_FAILED = "Signature validation failed.";
|
||||
string constant INVALID_SENDER = "Invalid `msg.sender`.";
|
||||
string constant INVALID_CONTEXT = "Function called in an invalid context.";
|
||||
string constant INVALID_NEW_MAKER_EPOCH = "Specified salt must be greater than or equal to existing makerEpoch.";
|
||||
|
||||
// Transaction revert reasons
|
||||
string constant DUPLICATE_TRANSACTION_HASH = "Transaction has already been executed.";
|
||||
string constant TRANSACTION_EXECUTION_FAILED = "Transaction execution failed.";
|
||||
|
||||
// Wrapper revert reasons
|
||||
string constant COMPLETE_FILL_FAILED = "Desired fill amount could not be completely filled.";
|
||||
string constant ASSET_DATA_MISMATCH = "Asset data must be the same for each order.";
|
||||
|
||||
// Asset proxy dispatcher revert reasons
|
||||
string constant GREATER_THAN_ZERO_LENGTH_REQUIRED = "Length must be greater than 0.";
|
||||
string constant OLD_ASSET_PROXY_MISMATCH = "Old asset proxy does not match asset proxy at given id.";
|
||||
string constant NEW_ASSET_PROXY_MISMATCH = "New asset proxy id does not match given id.";
|
||||
|
||||
// Signature validator revert reasons
|
||||
string constant INVALID_SIGNATURE_LENGTH = "Invalid signature length.";
|
||||
string constant ILLEGAL_SIGNATURE_TYPE = "Illegal signature type.";
|
||||
string constant UNSUPPORTED_SIGNATURE_TYPE = "Unsupported signature type.";
|
||||
}
|
@@ -16,12 +16,14 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../utils/SafeMath/SafeMath.sol";
|
||||
|
||||
contract LibFillResults is SafeMath {
|
||||
contract LibFillResults is
|
||||
SafeMath
|
||||
{
|
||||
|
||||
struct FillResults {
|
||||
uint256 makerAssetFilledAmount;
|
||||
|
@@ -16,12 +16,14 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../utils/SafeMath/SafeMath.sol";
|
||||
|
||||
contract LibMath is SafeMath {
|
||||
contract LibMath is
|
||||
SafeMath
|
||||
{
|
||||
|
||||
/// @dev Calculates partial value given a numerator and denominator.
|
||||
/// @param numerator Numerator.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract LibOrder {
|
||||
|
@@ -16,13 +16,16 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../utils/Ownable/Ownable.sol";
|
||||
import "../AssetProxy/IAssetProxy.sol";
|
||||
import "./LibExchangeErrors.sol";
|
||||
import "./mixins/MAssetProxyDispatcher.sol";
|
||||
|
||||
contract MixinAssetProxyDispatcher is
|
||||
LibExchangeErrors,
|
||||
Ownable,
|
||||
MAssetProxyDispatcher
|
||||
{
|
||||
@@ -43,8 +46,11 @@ contract MixinAssetProxyDispatcher is
|
||||
{
|
||||
// Do nothing if no amount should be transferred.
|
||||
if (amount > 0) {
|
||||
// Lookup asset proxy.
|
||||
require(assetMetadata.length >= 1);
|
||||
// Lookup asset proxy
|
||||
require(
|
||||
assetMetadata.length >= 1,
|
||||
GREATER_THAN_ZERO_LENGTH_REQUIRED
|
||||
);
|
||||
uint8 assetProxyId = uint8(assetMetadata[0]);
|
||||
IAssetProxy assetProxy = assetProxies[assetProxyId];
|
||||
|
||||
@@ -65,15 +71,21 @@ contract MixinAssetProxyDispatcher is
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
// Ensure the existing asset proxy is not unintentionally overwritten.
|
||||
require(oldAssetProxy == address(assetProxies[assetProxyId]));
|
||||
// Ensure the existing asset proxy is not unintentionally overwritten
|
||||
require(
|
||||
oldAssetProxy == address(assetProxies[assetProxyId]),
|
||||
OLD_ASSET_PROXY_MISMATCH
|
||||
);
|
||||
|
||||
IAssetProxy assetProxy = IAssetProxy(newAssetProxy);
|
||||
|
||||
// Ensure that the id of newAssetProxy matches the passed in assetProxyId, unless it is being reset to 0.
|
||||
if (newAssetProxy != address(0)) {
|
||||
uint8 newAssetProxyId = assetProxy.getProxyId();
|
||||
require(newAssetProxyId == assetProxyId);
|
||||
require(
|
||||
newAssetProxyId == assetProxyId,
|
||||
NEW_ASSET_PROXY_MISMATCH
|
||||
);
|
||||
}
|
||||
|
||||
// Add asset proxy and log registration.
|
||||
@@ -89,7 +101,7 @@ contract MixinAssetProxyDispatcher is
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
IAssetProxy assetProxy = assetProxies[assetProxyId];
|
||||
return address(assetProxy);
|
||||
address assetProxy = address(assetProxies[assetProxyId]);
|
||||
return assetProxy;
|
||||
}
|
||||
}
|
||||
|
@@ -16,13 +16,13 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./LibFillResults.sol";
|
||||
import "./LibOrder.sol";
|
||||
import "./LibErrors.sol";
|
||||
import "./LibMath.sol";
|
||||
import "./LibExchangeErrors.sol";
|
||||
import "./mixins/MExchangeCore.sol";
|
||||
import "./mixins/MSettlement.sol";
|
||||
import "./mixins/MSignatureValidator.sol";
|
||||
@@ -34,8 +34,8 @@ import "./mixins/MTransactions.sol";
|
||||
contract MixinExchangeCore is
|
||||
LibOrder,
|
||||
LibFillResults,
|
||||
LibErrors,
|
||||
LibMath,
|
||||
LibExchangeErrors,
|
||||
MExchangeCore,
|
||||
MSettlement,
|
||||
MSignatureValidator,
|
||||
@@ -111,22 +111,40 @@ contract MixinExchangeCore is
|
||||
// Validate order and maker only if first time seen
|
||||
// TODO: Read filled and cancelled only once
|
||||
if (filled[orderHash] == 0) {
|
||||
require(order.makerAssetAmount > 0);
|
||||
require(order.takerAssetAmount > 0);
|
||||
require(isValidSignature(orderHash, order.makerAddress, signature));
|
||||
require(
|
||||
order.makerAssetAmount > 0,
|
||||
GREATER_THAN_ZERO_AMOUNT_REQUIRED
|
||||
);
|
||||
require(
|
||||
order.takerAssetAmount > 0,
|
||||
GREATER_THAN_ZERO_AMOUNT_REQUIRED
|
||||
);
|
||||
require(
|
||||
isValidSignature(orderHash, order.makerAddress, signature),
|
||||
SIGNATURE_VALIDATION_FAILED
|
||||
);
|
||||
}
|
||||
|
||||
// Validate sender is allowed to fill this order
|
||||
if (order.senderAddress != address(0)) {
|
||||
require(order.senderAddress == msg.sender);
|
||||
require(
|
||||
order.senderAddress == msg.sender,
|
||||
INVALID_SENDER
|
||||
);
|
||||
}
|
||||
|
||||
// Validate taker is allowed to fill this order
|
||||
address takerAddress = getCurrentContextAddress();
|
||||
if (order.takerAddress != address(0)) {
|
||||
require(order.takerAddress == takerAddress);
|
||||
require(
|
||||
order.takerAddress == takerAddress,
|
||||
INVALID_CONTEXT
|
||||
);
|
||||
}
|
||||
require(takerAssetFillAmount > 0);
|
||||
require(
|
||||
takerAssetFillAmount > 0,
|
||||
GREATER_THAN_ZERO_AMOUNT_REQUIRED
|
||||
);
|
||||
|
||||
// Validate order expiration
|
||||
if (block.timestamp >= order.expirationTimeSeconds) {
|
||||
@@ -173,17 +191,29 @@ contract MixinExchangeCore is
|
||||
bytes32 orderHash = getOrderHash(order);
|
||||
|
||||
// Validate the order
|
||||
require(order.makerAssetAmount > 0);
|
||||
require(order.takerAssetAmount > 0);
|
||||
require(
|
||||
order.makerAssetAmount > 0,
|
||||
GREATER_THAN_ZERO_AMOUNT_REQUIRED
|
||||
);
|
||||
require(
|
||||
order.takerAssetAmount > 0,
|
||||
GREATER_THAN_ZERO_AMOUNT_REQUIRED
|
||||
);
|
||||
|
||||
// Validate sender is allowed to cancel this order
|
||||
if (order.senderAddress != address(0)) {
|
||||
require(order.senderAddress == msg.sender);
|
||||
require(
|
||||
order.senderAddress == msg.sender,
|
||||
INVALID_SENDER
|
||||
);
|
||||
}
|
||||
|
||||
// Validate transaction signed by maker
|
||||
address makerAddress = getCurrentContextAddress();
|
||||
require(order.makerAddress == makerAddress);
|
||||
require(
|
||||
order.makerAddress == makerAddress,
|
||||
INVALID_CONTEXT
|
||||
);
|
||||
|
||||
if (block.timestamp >= order.expirationTimeSeconds) {
|
||||
emit ExchangeError(uint8(Errors.ORDER_EXPIRED), orderHash);
|
||||
@@ -211,8 +241,11 @@ contract MixinExchangeCore is
|
||||
function cancelOrdersUpTo(uint256 salt)
|
||||
external
|
||||
{
|
||||
uint256 newMakerEpoch = salt + 1; // makerEpoch is initialized to 0, so to cancelUpTo we need salt+1
|
||||
require(newMakerEpoch > makerEpoch[msg.sender]); // epoch must be monotonically increasing
|
||||
uint256 newMakerEpoch = salt + 1; // makerEpoch is initialized to 0, so to cancelUpTo we need salt + 1
|
||||
require(
|
||||
newMakerEpoch > makerEpoch[msg.sender], // epoch must be monotonically increasing
|
||||
INVALID_NEW_MAKER_EPOCH
|
||||
);
|
||||
makerEpoch[msg.sender] = newMakerEpoch;
|
||||
emit CancelUpTo(msg.sender, newMakerEpoch);
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./mixins/MSettlement.sol";
|
||||
@@ -41,7 +41,7 @@ contract MixinSettlement is
|
||||
return ZRX_PROXY_DATA;
|
||||
}
|
||||
|
||||
function MixinSettlement(bytes memory _zrxProxyData)
|
||||
constructor (bytes memory _zrxProxyData)
|
||||
public
|
||||
{
|
||||
ZRX_PROXY_DATA = _zrxProxyData;
|
||||
|
@@ -16,15 +16,20 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./mixins/MSignatureValidator.sol";
|
||||
import "./ISigner.sol";
|
||||
import "./LibExchangeErrors.sol";
|
||||
import "../../utils/LibBytes/LibBytes.sol";
|
||||
|
||||
/// @dev Provides MSignatureValidator
|
||||
contract MixinSignatureValidator is MSignatureValidator {
|
||||
|
||||
contract MixinSignatureValidator is
|
||||
LibBytes,
|
||||
LibExchangeErrors,
|
||||
MSignatureValidator
|
||||
{
|
||||
enum SignatureType {
|
||||
Illegal, // Default value
|
||||
Invalid,
|
||||
@@ -54,7 +59,10 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
{
|
||||
// TODO: Domain separation: make hash depend on role. (Taker sig should not be valid as maker sig, etc.)
|
||||
|
||||
require(signature.length >= 1);
|
||||
require(
|
||||
signature.length >= 1,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
SignatureType signatureType = SignatureType(uint8(signature[0]));
|
||||
|
||||
// Variables are not scoped in Solidity
|
||||
@@ -69,14 +77,18 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
// it an explicit option. This aids testing and analysis. It is
|
||||
// also the initialization value for the enum type.
|
||||
if (signatureType == SignatureType.Illegal) {
|
||||
revert();
|
||||
// NOTE: Reason cannot be assigned to a variable because of https://github.com/ethereum/solidity/issues/4051
|
||||
revert("Illegal signature type.");
|
||||
|
||||
// Always invalid signature
|
||||
// Like Illegal, this is always implicitly available and therefore
|
||||
// offered explicitly. It can be implicitly created by providing
|
||||
// a correctly formatted but incorrect signature.
|
||||
} else if (signatureType == SignatureType.Invalid) {
|
||||
require(signature.length == 1);
|
||||
require(
|
||||
signature.length == 1,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
isValid = false;
|
||||
return isValid;
|
||||
|
||||
@@ -89,16 +101,22 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
// `Caller` for his own signature. Or A and C can sign and B can
|
||||
// submit using `Caller`. Having `Caller` allows this flexibility.
|
||||
} else if (signatureType == SignatureType.Caller) {
|
||||
require(signature.length == 1);
|
||||
require(
|
||||
signature.length == 1,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
isValid = signer == msg.sender;
|
||||
return isValid;
|
||||
|
||||
// Signed using web3.eth_sign
|
||||
} else if (signatureType == SignatureType.Ecrecover) {
|
||||
require(signature.length == 66);
|
||||
require(
|
||||
signature.length == 66,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
v = uint8(signature[1]);
|
||||
r = get32(signature, 2);
|
||||
s = get32(signature, 34);
|
||||
r = readBytes32(signature, 2);
|
||||
s = readBytes32(signature, 34);
|
||||
recovered = ecrecover(
|
||||
keccak256("\x19Ethereum Signed Message:\n32", hash),
|
||||
v,
|
||||
@@ -110,10 +128,13 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
|
||||
// Signature using EIP712
|
||||
} else if (signatureType == SignatureType.EIP712) {
|
||||
require(signature.length == 66);
|
||||
require(
|
||||
signature.length == 66,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
v = uint8(signature[1]);
|
||||
r = get32(signature, 2);
|
||||
s = get32(signature, 34);
|
||||
r = readBytes32(signature, 2);
|
||||
s = readBytes32(signature, 34);
|
||||
recovered = ecrecover(hash, v, r, s);
|
||||
isValid = signer == recovered;
|
||||
return isValid;
|
||||
@@ -127,10 +148,13 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
// https://github.com/trezor/trezor-mcu/blob/master/firmware/ethereum.c#L602
|
||||
// https://github.com/trezor/trezor-mcu/blob/master/firmware/crypto.c#L36
|
||||
} else if (signatureType == SignatureType.Trezor) {
|
||||
require(signature.length == 66);
|
||||
require(
|
||||
signature.length == 66,
|
||||
INVALID_SIGNATURE_LENGTH
|
||||
);
|
||||
v = uint8(signature[1]);
|
||||
r = get32(signature, 2);
|
||||
s = get32(signature, 34);
|
||||
r = readBytes32(signature, 2);
|
||||
s = readBytes32(signature, 34);
|
||||
recovered = ecrecover(
|
||||
keccak256("\x19Ethereum Signed Message:\n\x41", hash),
|
||||
v,
|
||||
@@ -156,7 +180,8 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
// that we currently support. In this case returning false
|
||||
// may lead the caller to incorrectly believe that the
|
||||
// signature was invalid.)
|
||||
revert();
|
||||
// NOTE: Reason cannot be assigned to a variable because of https://github.com/ethereum/solidity/issues/4051
|
||||
revert("Unsupported signature type.");
|
||||
}
|
||||
|
||||
/// @dev Approves a hash on-chain using any valid signature type.
|
||||
@@ -169,24 +194,10 @@ contract MixinSignatureValidator is MSignatureValidator {
|
||||
bytes signature)
|
||||
external
|
||||
{
|
||||
require(isValidSignature(hash, signer, signature));
|
||||
require(
|
||||
isValidSignature(hash, signer, signature),
|
||||
SIGNATURE_VALIDATION_FAILED
|
||||
);
|
||||
preSigned[hash][signer] = true;
|
||||
}
|
||||
|
||||
function get32(bytes memory b, uint256 index)
|
||||
private pure
|
||||
returns (bytes32 result)
|
||||
{
|
||||
require(b.length >= index + 32);
|
||||
|
||||
// Arrays are prefixed by a 256 bit length parameter
|
||||
index += 32;
|
||||
|
||||
// Read the bytes32 from array memory
|
||||
assembly {
|
||||
result := mload(add(b, index))
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -20,8 +20,10 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./mixins/MSignatureValidator.sol";
|
||||
import "./mixins/MTransactions.sol";
|
||||
import "./LibExchangeErrors.sol";
|
||||
|
||||
contract MixinTransactions is
|
||||
LibExchangeErrors,
|
||||
MSignatureValidator,
|
||||
MTransactions
|
||||
{
|
||||
@@ -56,12 +58,18 @@ contract MixinTransactions is
|
||||
);
|
||||
|
||||
// Validate transaction has not been executed
|
||||
require(!transactions[transactionHash]);
|
||||
require(
|
||||
!transactions[transactionHash],
|
||||
DUPLICATE_TRANSACTION_HASH
|
||||
);
|
||||
|
||||
// TODO: is SignatureType.Caller necessary if we make this check?
|
||||
if (signer != msg.sender) {
|
||||
// Validate signature
|
||||
require(isValidSignature(transactionHash, signer, signature));
|
||||
require(
|
||||
isValidSignature(transactionHash, signer, signature),
|
||||
SIGNATURE_VALIDATION_FAILED
|
||||
);
|
||||
|
||||
// Set the current transaction signer
|
||||
currentContextAddress = signer;
|
||||
@@ -69,7 +77,10 @@ contract MixinTransactions is
|
||||
|
||||
// Execute transaction
|
||||
transactions[transactionHash] = true;
|
||||
require(address(this).delegatecall(data));
|
||||
require(
|
||||
address(this).delegatecall(data),
|
||||
TRANSACTION_EXECUTION_FAILED
|
||||
);
|
||||
|
||||
// Reset current transaction signer
|
||||
// TODO: Check if gas is paid when currentContextAddress is already 0.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../utils/LibBytes/LibBytes.sol";
|
||||
@@ -24,6 +24,7 @@ import "./mixins/MExchangeCore.sol";
|
||||
import "./LibMath.sol";
|
||||
import "./LibOrder.sol";
|
||||
import "./LibFillResults.sol";
|
||||
import "./LibExchangeErrors.sol";
|
||||
|
||||
/// @dev Consumes MExchangeCore
|
||||
contract MixinWrapperFunctions is
|
||||
@@ -31,6 +32,7 @@ contract MixinWrapperFunctions is
|
||||
LibFillResults,
|
||||
LibMath,
|
||||
LibBytes,
|
||||
LibExchangeErrors,
|
||||
MExchangeCore
|
||||
{
|
||||
/// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
|
||||
@@ -49,7 +51,10 @@ contract MixinWrapperFunctions is
|
||||
takerAssetFillAmount,
|
||||
signature
|
||||
);
|
||||
require(fillResults.takerAssetFilledAmount == takerAssetFillAmount);
|
||||
require(
|
||||
fillResults.takerAssetFilledAmount == takerAssetFillAmount,
|
||||
COMPLETE_FILL_FAILED
|
||||
);
|
||||
return fillResults;
|
||||
}
|
||||
|
||||
@@ -327,7 +332,11 @@ contract MixinWrapperFunctions is
|
||||
for (uint256 i = 0; i < orders.length; i++) {
|
||||
|
||||
// Token being sold by taker must be the same for each order
|
||||
require(areBytesEqual(orders[i].takerAssetData, orders[0].takerAssetData));
|
||||
// TODO: optimize by only using takerAssetData for first order.
|
||||
require(
|
||||
areBytesEqual(orders[i].takerAssetData, orders[0].takerAssetData),
|
||||
ASSET_DATA_MISMATCH
|
||||
);
|
||||
|
||||
// Calculate the remaining amount of takerAsset to sell
|
||||
uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);
|
||||
@@ -366,7 +375,11 @@ contract MixinWrapperFunctions is
|
||||
for (uint256 i = 0; i < orders.length; i++) {
|
||||
|
||||
// Token being sold by taker must be the same for each order
|
||||
require(areBytesEqual(orders[i].takerAssetData, orders[0].takerAssetData));
|
||||
// TODO: optimize by only using takerAssetData for first order.
|
||||
require(
|
||||
areBytesEqual(orders[i].takerAssetData, orders[0].takerAssetData),
|
||||
ASSET_DATA_MISMATCH
|
||||
);
|
||||
|
||||
// Calculate the remaining amount of takerAsset to sell
|
||||
uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);
|
||||
@@ -404,7 +417,11 @@ contract MixinWrapperFunctions is
|
||||
for (uint256 i = 0; i < orders.length; i++) {
|
||||
|
||||
// Token being bought by taker must be the same for each order
|
||||
require(areBytesEqual(orders[i].makerAssetData, orders[0].makerAssetData));
|
||||
// TODO: optimize by only using makerAssetData for first order.
|
||||
require(
|
||||
areBytesEqual(orders[i].makerAssetData, orders[0].makerAssetData),
|
||||
ASSET_DATA_MISMATCH
|
||||
);
|
||||
|
||||
// Calculate the remaining amount of makerAsset to buy
|
||||
uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
|
||||
@@ -451,7 +468,11 @@ contract MixinWrapperFunctions is
|
||||
for (uint256 i = 0; i < orders.length; i++) {
|
||||
|
||||
// Token being bought by taker must be the same for each order
|
||||
require(areBytesEqual(orders[i].makerAssetData, orders[0].makerAssetData));
|
||||
// TODO: optimize by only using makerAssetData for first order.
|
||||
require(
|
||||
areBytesEqual(orders[i].makerAssetData, orders[0].makerAssetData),
|
||||
ASSET_DATA_MISMATCH
|
||||
);
|
||||
|
||||
// Calculate the remaining amount of makerAsset to buy
|
||||
uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract MAssetProxyDispatcher {
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../LibOrder.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../LibOrder.sol";
|
||||
@@ -33,5 +33,5 @@ contract MSettlement {
|
||||
uint256 makerFeePaid,
|
||||
uint256 takerFeePaid
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract MSignatureValidator {
|
||||
|
@@ -15,12 +15,10 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./MSignatureValidator.sol";
|
||||
|
||||
contract MTransactions is MSignatureValidator {
|
||||
contract MTransactions {
|
||||
|
||||
/// @dev Executes an exchange method call in the context of signer.
|
||||
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../Mintable/Mintable.sol";
|
||||
import "../../utils/Ownable/Ownable.sol";
|
||||
@@ -26,7 +27,7 @@ contract DummyERC20Token is Mintable, Ownable {
|
||||
string public symbol;
|
||||
uint256 public decimals;
|
||||
|
||||
function DummyERC20Token(
|
||||
constructor (
|
||||
string _name,
|
||||
string _symbol,
|
||||
uint256 _decimals,
|
||||
|
@@ -16,7 +16,9 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../tokens/ERC721Token/ERC721Token.sol";
|
||||
import "../../utils/Ownable/Ownable.sol";
|
||||
|
||||
@@ -30,7 +32,7 @@ contract DummyERC721Token is
|
||||
* @param name of token
|
||||
* @param symbol of token
|
||||
*/
|
||||
function DummyERC721Token(
|
||||
constructor (
|
||||
string name,
|
||||
string symbol)
|
||||
public
|
||||
@@ -47,7 +49,10 @@ contract DummyERC721Token is
|
||||
public
|
||||
onlyOwner
|
||||
{
|
||||
require(!exists(tokenId));
|
||||
require(
|
||||
!exists(tokenId),
|
||||
"Token with tokenId already exists."
|
||||
);
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../tokens/UnlimitedAllowanceToken/UnlimitedAllowanceToken.sol";
|
||||
import "../../utils/SafeMath/SafeMath.sol";
|
||||
@@ -29,7 +30,10 @@ contract Mintable is UnlimitedAllowanceToken, SafeMath {
|
||||
function mint(uint256 _value)
|
||||
public
|
||||
{
|
||||
require(_value <= 100000000000000000000);
|
||||
require(
|
||||
_value <= 100000000000000000000,
|
||||
"Minting more than 100000000000000000000 is not allowed."
|
||||
);
|
||||
balances[msg.sender] = safeAdd(_value, balances[msg.sender]);
|
||||
totalSupply = safeAdd(totalSupply, _value);
|
||||
}
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../protocol/Exchange/MixinAssetProxyDispatcher.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../protocol/Exchange/LibMath.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../../protocol/Exchange/MixinSignatureValidator.sol";
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.18;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IERC20Token.sol";
|
||||
|
||||
@@ -26,7 +27,14 @@ contract ERC20Token is IERC20Token {
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
require(balances[msg.sender] >= _value && balances[_to] + _value >= balances[_to]);
|
||||
require(
|
||||
balances[msg.sender] >= _value,
|
||||
"Insufficient balance to complete transfer."
|
||||
);
|
||||
require(
|
||||
balances[_to] + _value >= balances[_to],
|
||||
"Transfer would result in an overflow."
|
||||
);
|
||||
balances[msg.sender] -= _value;
|
||||
balances[_to] += _value;
|
||||
emit Transfer(msg.sender, _to, _value);
|
||||
@@ -37,7 +45,18 @@ contract ERC20Token is IERC20Token {
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value >= balances[_to]);
|
||||
require(
|
||||
balances[_from] >= _value,
|
||||
"Insufficient balance to complete transfer."
|
||||
);
|
||||
require(
|
||||
allowed[_from][msg.sender] >= _value,
|
||||
"Insufficient allowance to complete transfer."
|
||||
);
|
||||
require(
|
||||
balances[_to] + _value >= balances[_to],
|
||||
"Transfer would result in an overflow."
|
||||
);
|
||||
balances[_to] += _value;
|
||||
balances[_from] -= _value;
|
||||
allowed[_from][msg.sender] -= _value;
|
||||
|
@@ -16,11 +16,12 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.18;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract IERC20Token {
|
||||
|
||||
/// @notice send `_value` token to `_to` from `msg.sender`
|
||||
/// @notice send `value` token to `to` from `msg.sender`
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _value The amount of token to be transferred
|
||||
/// @return Whether the transfer was successful or not
|
||||
@@ -28,7 +29,7 @@ contract IERC20Token {
|
||||
public
|
||||
returns (bool);
|
||||
|
||||
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
|
||||
/// @notice send `value` token to `to` from `from` on the condition it is approved by `from`
|
||||
/// @param _from The address of the sender
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _value The amount of token to be transferred
|
||||
@@ -61,10 +62,12 @@ contract IERC20Token {
|
||||
event Transfer(
|
||||
address indexed _from,
|
||||
address indexed _to,
|
||||
uint256 _value);
|
||||
uint256 _value
|
||||
);
|
||||
|
||||
event Approval(
|
||||
address indexed _owner,
|
||||
address indexed _spender,
|
||||
uint256 _value);
|
||||
uint256 _value
|
||||
);
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
|
||||
import "./IERC721Token.sol";
|
||||
import "./IERC721Receiver.sol";
|
||||
|
@@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
|
||||
/**
|
||||
* @title ERC721 token receiver interface
|
||||
|
@@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
|
||||
/**
|
||||
* @title ERC721 Non-Fungible Token Standard basic interface
|
||||
|
@@ -16,9 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.18;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { ERC20Token } from "../ERC20Token/ERC20Token.sol";
|
||||
import "../ERC20Token/ERC20Token.sol";
|
||||
|
||||
contract UnlimitedAllowanceToken is ERC20Token {
|
||||
|
||||
@@ -34,7 +35,18 @@ contract UnlimitedAllowanceToken is ERC20Token {
|
||||
returns (bool)
|
||||
{
|
||||
uint256 allowance = allowed[_from][msg.sender];
|
||||
require(balances[_from] >= _value && allowance >= _value && balances[_to] + _value >= balances[_to]);
|
||||
require(
|
||||
balances[_from] >= _value,
|
||||
"Insufficient balance to complete transfer."
|
||||
);
|
||||
require(
|
||||
allowance >= _value,
|
||||
"Insufficient allowance to complete transfer."
|
||||
);
|
||||
require(
|
||||
balances[_to] + _value >= balances[_to],
|
||||
"Transfer would result in an overflow."
|
||||
);
|
||||
balances[_to] += _value;
|
||||
balances[_from] -= _value;
|
||||
if (allowance < MAX_UINT) {
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IAuthorizable.sol";
|
||||
import "../Ownable/Ownable.sol";
|
||||
@@ -28,17 +29,26 @@ contract Authorizable is
|
||||
|
||||
/// @dev Only authorized addresses can invoke functions with this modifier.
|
||||
modifier onlyAuthorized {
|
||||
require(authorized[msg.sender]);
|
||||
require(
|
||||
authorized[msg.sender],
|
||||
"Sender not authorized to call this method."
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier targetAuthorized(address target) {
|
||||
require(authorized[target]);
|
||||
require(
|
||||
authorized[target],
|
||||
"Target address not authorized to call this method."
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier targetNotAuthorized(address target) {
|
||||
require(!authorized[target]);
|
||||
require(
|
||||
!authorized[target],
|
||||
"Target must not already be authorized to call this method."
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
@@ -85,8 +95,14 @@ contract Authorizable is
|
||||
function removeAuthorizedAddressAtIndex(address target, uint256 index)
|
||||
public
|
||||
{
|
||||
require(index < authorities.length);
|
||||
require(authorities[index] == target);
|
||||
require(
|
||||
index < authorities.length,
|
||||
"Specified index is out of bounds."
|
||||
);
|
||||
require(
|
||||
authorities[index] == target,
|
||||
"Address found at index does not match target address."
|
||||
);
|
||||
delete authorized[target];
|
||||
authorities[index] = authorities[authorities.length - 1];
|
||||
authorities.length -= 1;
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract IAuthorizable {
|
||||
|
||||
@@ -44,9 +45,11 @@ contract IAuthorizable {
|
||||
|
||||
event AuthorizedAddressAdded(
|
||||
address indexed target,
|
||||
address indexed caller);
|
||||
address indexed caller
|
||||
);
|
||||
|
||||
event AuthorizedAddressRemoved(
|
||||
address indexed target,
|
||||
address indexed caller);
|
||||
address indexed caller
|
||||
);
|
||||
}
|
||||
|
@@ -16,7 +16,8 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract LibBytes {
|
||||
|
||||
@@ -61,7 +62,10 @@ contract LibBytes {
|
||||
public pure
|
||||
returns (address result)
|
||||
{
|
||||
require(b.length >= index + 20); // 20 is length of address
|
||||
require(
|
||||
b.length >= index + 20, // 20 is length of address
|
||||
"Cannot read address from byte array shorter than 20 bytes."
|
||||
);
|
||||
|
||||
// Add offset to index:
|
||||
// 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
|
||||
@@ -88,7 +92,10 @@ contract LibBytes {
|
||||
address input)
|
||||
public pure
|
||||
{
|
||||
require(b.length >= index + 20); // 20 is length of address
|
||||
require(
|
||||
b.length >= index + 20, // 20 is length of address
|
||||
"Cannot write address to byte array shorter than 20 bytes."
|
||||
);
|
||||
|
||||
// Add offset to index:
|
||||
// 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
|
||||
@@ -122,7 +129,10 @@ contract LibBytes {
|
||||
public pure
|
||||
returns (bytes32 result)
|
||||
{
|
||||
require(b.length >= index + 32);
|
||||
require(
|
||||
b.length >= index + 32,
|
||||
"Cannot read 32 bytes from byte array shorter than 32 bytes."
|
||||
);
|
||||
|
||||
// Arrays are prefixed by a 256 bit length parameter
|
||||
index += 32;
|
||||
@@ -144,7 +154,10 @@ contract LibBytes {
|
||||
bytes32 input)
|
||||
public pure
|
||||
{
|
||||
require(b.length >= index + 32);
|
||||
require(
|
||||
b.length >= index + 32,
|
||||
"Cannot write 32 bytes to byte array shorter than 32 bytes."
|
||||
);
|
||||
|
||||
// Arrays are prefixed by a 256 bit length parameter
|
||||
index += 32;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/*
|
||||
* Ownable
|
||||
|
@@ -1,4 +1,5 @@
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/*
|
||||
* Ownable
|
||||
@@ -12,14 +13,17 @@ import "../Ownable/IOwnable.sol";
|
||||
contract Ownable is IOwnable {
|
||||
address public owner;
|
||||
|
||||
function Ownable()
|
||||
constructor ()
|
||||
public
|
||||
{
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
modifier onlyOwner() {
|
||||
require(msg.sender == owner);
|
||||
require(
|
||||
msg.sender == owner,
|
||||
"Only contract owner is allowed to call this method."
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
pragma solidity ^0.4.21;
|
||||
pragma solidity ^0.4.23;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract SafeMath {
|
||||
function safeMul(uint a, uint b)
|
||||
|
Reference in New Issue
Block a user