aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src
diff options
context:
space:
mode:
authorAmir Bandeali <abandeali1@gmail.com>2018-08-24 15:19:06 +0800
committerAmir Bandeali <abandeali1@gmail.com>2018-08-25 04:19:07 +0800
commit0a1ae2c31139e446b2fb3b7f03caf371c6668ae2 (patch)
tree3408f2db59daf3762dcb4244f52e3389c97849df /packages/contracts/src
parentc5f8b9c2d2b1eed5789b40c4df07e98afe0431ab (diff)
downloaddexon-0x-contracts-0a1ae2c31139e446b2fb3b7f03caf371c6668ae2.tar.gz
dexon-0x-contracts-0a1ae2c31139e446b2fb3b7f03caf371c6668ae2.tar.zst
dexon-0x-contracts-0a1ae2c31139e446b2fb3b7f03caf371c6668ae2.zip
Remove pragma experimental v0.5.0 and use staticcall is assembly
Diffstat (limited to 'packages/contracts/src')
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol84
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol31
-rw-r--r--packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol1
-rw-r--r--packages/contracts/src/2.0.0/test/TestStaticCall/TestStaticCall.sol16
4 files changed, 128 insertions, 4 deletions
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol
index fd655e757..6bfbb5107 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol
@@ -17,7 +17,6 @@
*/
pragma solidity 0.4.24;
-pragma experimental "v0.5.0";
import "../../utils/LibBytes/LibBytes.sol";
import "./mixins/MSignatureValidator.sol";
@@ -192,7 +191,11 @@ contract MixinSignatureValidator is
// Signature verified by wallet contract.
// If used with an order, the maker of the order is the wallet contract.
} else if (signatureType == SignatureType.Wallet) {
- isValid = IWallet(signerAddress).isValidSignature(hash, signature);
+ isValid = isValidWalletSignature(
+ hash,
+ signerAddress,
+ signature
+ );
return isValid;
// Signature verified by validator contract.
@@ -210,7 +213,8 @@ contract MixinSignatureValidator is
if (!allowedValidators[signerAddress][validatorAddress]) {
return false;
}
- isValid = IValidator(validatorAddress).isValidSignature(
+ isValid = isValidValidatorSignature(
+ validatorAddress,
hash,
signerAddress,
signature
@@ -258,4 +262,78 @@ contract MixinSignatureValidator is
// signature was invalid.)
revert("SIGNATURE_UNSUPPORTED");
}
+
+ /// @dev Verifies signature using logic defined by Wallet contract.
+ /// @param hash Any 32 byte hash.
+ /// @param walletAddress Address that should have signed the given hash
+ /// and defines its own signature verification method.
+ /// @param signature Proof that the hash has been signed by signer.
+ /// @return True if signature is valid for given wallet..
+ function isValidWalletSignature(
+ bytes32 hash,
+ address walletAddress,
+ bytes signature
+ )
+ internal
+ view
+ returns (bool isValid)
+ {
+ bytes memory calldata = abi.encodeWithSelector(
+ IWallet(walletAddress).isValidSignature.selector,
+ hash,
+ signature
+ );
+ assembly {
+ let cdStart := add(calldata, 32)
+ let success := staticcall(
+ gas, // forward all gas
+ walletAddress, // address of Wallet contract
+ cdStart, // pointer to start of input
+ mload(calldata), // length of input
+ cdStart, // write input over output
+ 32 // output size is 32 bytes
+ )
+ // Signature is valid if call did not revert and returned true
+ isValid := and(success, mload(cdStart))
+ }
+ return isValid;
+ }
+
+ /// @dev Verifies signature using logic defined by Validator contract.
+ /// @param validatorAddress Address of validator contract.
+ /// @param hash Any 32 byte hash.
+ /// @param signerAddress Address that should have signed the given hash.
+ /// @param signature Proof that the hash has been signed by signer.
+ /// @return True if the address recovered from the provided signature matches the input signer address.
+ function isValidValidatorSignature(
+ address validatorAddress,
+ bytes32 hash,
+ address signerAddress,
+ bytes signature
+ )
+ internal
+ view
+ returns (bool isValid)
+ {
+ bytes memory calldata = abi.encodeWithSelector(
+ IValidator(signerAddress).isValidSignature.selector,
+ hash,
+ signerAddress,
+ signature
+ );
+ assembly {
+ let cdStart := add(calldata, 32)
+ let success := staticcall(
+ gas, // forward all gas
+ validatorAddress, // address of Validator contract
+ cdStart, // pointer to start of input
+ mload(calldata), // length of input
+ cdStart, // write input over output
+ 32 // output size is 32 bytes
+ )
+ // Signature is valid if call did not revert and returned true
+ isValid := and(success, mload(cdStart))
+ }
+ return isValid;
+ }
}
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol
index f14f2ba00..75fe9ec46 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MSignatureValidator.sol
@@ -43,4 +43,35 @@ contract MSignatureValidator is
Trezor, // 0x08
NSignatureTypes // 0x09, number of signature types. Always leave at end.
}
+
+ /// @dev Verifies signature using logic defined by Wallet contract.
+ /// @param hash Any 32 byte hash.
+ /// @param walletAddress Address that should have signed the given hash
+ /// and defines its own signature verification method.
+ /// @param signature Proof that the hash has been signed by signer.
+ /// @return True if the address recovered from the provided signature matches the input signer address.
+ function isValidWalletSignature(
+ bytes32 hash,
+ address walletAddress,
+ bytes signature
+ )
+ internal
+ view
+ returns (bool isValid);
+
+ /// @dev Verifies signature using logic defined by Validator contract.
+ /// @param validatorAddress Address of validator contract.
+ /// @param hash Any 32 byte hash.
+ /// @param signerAddress Address that should have signed the given hash.
+ /// @param signature Proof that the hash has been signed by signer.
+ /// @return True if the address recovered from the provided signature matches the input signer address.
+ function isValidValidatorSignature(
+ address validatorAddress,
+ bytes32 hash,
+ address signerAddress,
+ bytes signature
+ )
+ internal
+ view
+ returns (bool isValid);
}
diff --git a/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol b/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol
index 3845b7b9e..e1a610469 100644
--- a/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol
+++ b/packages/contracts/src/2.0.0/test/TestSignatureValidator/TestSignatureValidator.sol
@@ -17,7 +17,6 @@
*/
pragma solidity 0.4.24;
-pragma experimental "v0.5.0";
import "../../protocol/Exchange/MixinSignatureValidator.sol";
import "../../protocol/Exchange/MixinTransactions.sol";
diff --git a/packages/contracts/src/2.0.0/test/TestStaticCall/TestStaticCall.sol b/packages/contracts/src/2.0.0/test/TestStaticCall/TestStaticCall.sol
index be24e2f37..5a9581f51 100644
--- a/packages/contracts/src/2.0.0/test/TestStaticCall/TestStaticCall.sol
+++ b/packages/contracts/src/2.0.0/test/TestStaticCall/TestStaticCall.sol
@@ -18,6 +18,8 @@
pragma solidity 0.4.24;
+import "../../tokens/ERC20Token/IERC20Token.sol";
+
contract TestStaticCall {
@@ -55,6 +57,20 @@ contract TestStaticCall {
return true;
}
+ /// @dev Approves an ERC20 token to spend tokens from this address.
+ /// @param token Address of ERC20 token.
+ /// @param spender Address that will spend tokens.
+ /// @param value Amount of tokens spender is approved to spend.
+ function approveERC20(
+ address token,
+ address spender,
+ uint256 value
+ )
+ external
+ {
+ IERC20Token(token).approve(spender, value);
+ }
+
/// @dev Increments state variable.
function updateState()
internal