Remove approval expirations, address other comments
This commit is contained in:
parent
cf517b1459
commit
52fc7517f9
@ -67,11 +67,9 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-dev-utils @0x/contracts-staking
|
||||
- run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-exchange-forwarder @0x/contracts-dev-utils @0x/contracts-staking @0x/contracts-coordinator
|
||||
# TODO(dorothy-zbornak): Re-enable after updating this package for 3.0.
|
||||
# - run: yarn wsrun test:circleci @0x/contracts-extensions
|
||||
# TODO(abandeali): Re-enable after this package is complete.
|
||||
# - run: yarn wsrun test:circleci @0x/contracts-coordinator
|
||||
test-publish:
|
||||
resource_class: medium+
|
||||
docker:
|
||||
@ -82,7 +80,7 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run:
|
||||
- run:
|
||||
command: yarn test:publish:circleci
|
||||
no_output_timeout: 1800
|
||||
test-doc-generation:
|
||||
|
@ -47,15 +47,12 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each
|
||||
/// corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
|
||||
/// order in the transaction's Exchange calldata.
|
||||
function assertValidCoordinatorApprovals(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
public
|
||||
@ -72,7 +69,6 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
orders,
|
||||
txOrigin,
|
||||
transactionSignature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approvalSignatures
|
||||
);
|
||||
}
|
||||
@ -127,7 +123,7 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
orders = new LibOrder.Order[](2);
|
||||
orders[0] = leftOrder;
|
||||
orders[1] = rightOrder;
|
||||
}
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
|
||||
@ -136,15 +132,12 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
/// @param orders Array of order structs containing order specifications.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each
|
||||
/// corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
|
||||
function _assertValidTransactionOrdersApproval(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
LibOrder.Order[] memory orders,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
internal
|
||||
@ -164,23 +157,12 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
uint256 signaturesLength = approvalSignatures.length;
|
||||
for (uint256 i = 0; i != signaturesLength; i++) {
|
||||
// Create approval message
|
||||
uint256 currentApprovalExpirationTimeSeconds = approvalExpirationTimeSeconds[i];
|
||||
CoordinatorApproval memory approval = CoordinatorApproval({
|
||||
txOrigin: txOrigin,
|
||||
transactionHash: transactionHash,
|
||||
transactionSignature: transactionSignature,
|
||||
approvalExpirationTimeSeconds: currentApprovalExpirationTimeSeconds
|
||||
transactionSignature: transactionSignature
|
||||
});
|
||||
|
||||
// Ensure approval has not expired
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
if (currentApprovalExpirationTimeSeconds <= block.timestamp) {
|
||||
LibRichErrors.rrevert(LibCoordinatorRichErrors.ApprovalExpiredError(
|
||||
transactionHash,
|
||||
currentApprovalExpirationTimeSeconds
|
||||
));
|
||||
}
|
||||
|
||||
// Hash approval message and recover signer address
|
||||
bytes32 approvalHash = getCoordinatorApprovalHash(approval);
|
||||
address approvalSignerAddress = getSignerAddress(approvalHash, approvalSignatures[i]);
|
||||
|
@ -46,15 +46,12 @@ contract MixinCoordinatorCore is
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each
|
||||
/// corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
|
||||
/// order in the transaction's Exchange calldata.
|
||||
function executeTransaction(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
public
|
||||
@ -66,7 +63,6 @@ contract MixinCoordinatorCore is
|
||||
transaction,
|
||||
txOrigin,
|
||||
transactionSignature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approvalSignatures
|
||||
);
|
||||
|
||||
|
@ -30,15 +30,12 @@ contract ICoordinatorApprovalVerifier {
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each
|
||||
/// corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
|
||||
/// order in the transaction's Exchange calldata.
|
||||
function assertValidCoordinatorApprovals(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
public
|
||||
|
@ -29,15 +29,12 @@ contract ICoordinatorCore {
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each
|
||||
/// corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each
|
||||
/// order in the transaction's Exchange calldata.
|
||||
function executeTransaction(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
public
|
||||
|
@ -30,24 +30,22 @@ contract LibCoordinatorApproval is
|
||||
// "CoordinatorApproval(",
|
||||
// "address txOrigin,",
|
||||
// "bytes32 transactionHash,",
|
||||
// "bytes transactionSignature,",
|
||||
// "uint256 approvalExpirationTimeSeconds",
|
||||
// "bytes transactionSignature",
|
||||
// ")"
|
||||
// ));
|
||||
bytes32 constant public EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH =
|
||||
0x2fbcdbaa76bc7589916958ae919dfbef04d23f6bbf26de6ff317b32c6cc01e05;
|
||||
0xa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f8507168;
|
||||
|
||||
struct CoordinatorApproval {
|
||||
address txOrigin; // Required signer of Ethereum transaction that is submitting approval.
|
||||
bytes32 transactionHash; // EIP712 hash of the transaction.
|
||||
bytes transactionSignature; // Signature of the 0x transaction.
|
||||
uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the approval expires.
|
||||
}
|
||||
|
||||
/// @dev Calculates the EIP712 hash of the Coordinator approval mesasage using the domain
|
||||
/// separator of this contract.
|
||||
/// @param approval Coordinator approval message containing the transaction hash, transaction
|
||||
/// signature, and expiration of the approval.
|
||||
/// @param approval Coordinator approval message containing the transaction hash, and transaction
|
||||
/// signature.
|
||||
/// @return approvalHash EIP712 hash of the Coordinator approval message with the domain
|
||||
/// separator of this contract.
|
||||
function getCoordinatorApprovalHash(CoordinatorApproval memory approval)
|
||||
@ -60,8 +58,8 @@ contract LibCoordinatorApproval is
|
||||
}
|
||||
|
||||
/// @dev Calculates the EIP712 hash of the Coordinator approval mesasage with no domain separator.
|
||||
/// @param approval Coordinator approval message containing the transaction hash, transaction
|
||||
// signature, and expiration of the approval.
|
||||
/// @param approval Coordinator approval message containing the transaction hash, and transaction
|
||||
// signature.
|
||||
/// @return result EIP712 hash of the Coordinator approval message with no domain separator.
|
||||
function _hashCoordinatorApproval(CoordinatorApproval memory approval)
|
||||
internal
|
||||
@ -72,7 +70,6 @@ contract LibCoordinatorApproval is
|
||||
bytes memory transactionSignature = approval.transactionSignature;
|
||||
address txOrigin = approval.txOrigin;
|
||||
bytes32 transactionHash = approval.transactionHash;
|
||||
uint256 approvalExpirationTimeSeconds = approval.approvalExpirationTimeSeconds;
|
||||
|
||||
// Assembly for more efficiently computing:
|
||||
// keccak256(abi.encodePacked(
|
||||
@ -80,7 +77,6 @@ contract LibCoordinatorApproval is
|
||||
// approval.txOrigin,
|
||||
// approval.transactionHash,
|
||||
// keccak256(approval.transactionSignature)
|
||||
// approval.approvalExpirationTimeSeconds,
|
||||
// ));
|
||||
|
||||
assembly {
|
||||
@ -94,9 +90,8 @@ contract LibCoordinatorApproval is
|
||||
mstore(add(memPtr, 32), txOrigin) // txOrigin
|
||||
mstore(add(memPtr, 64), transactionHash) // transactionHash
|
||||
mstore(add(memPtr, 96), transactionSignatureHash) // transactionSignatureHash
|
||||
mstore(add(memPtr, 128), approvalExpirationTimeSeconds) // approvalExpirationTimeSeconds
|
||||
// Compute hash
|
||||
result := keccak256(memPtr, 160)
|
||||
result := keccak256(memPtr, 128)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -35,10 +35,6 @@ library LibCoordinatorRichErrors {
|
||||
bytes4 internal constant INVALID_ORIGIN_ERROR_SELECTOR =
|
||||
0xa458d7ff;
|
||||
|
||||
// bytes4(keccak256("ApprovalExpiredError(bytes32,uint256)"))
|
||||
bytes4 internal constant APPROVAL_EXPIRED_ERROR_SELECTOR =
|
||||
0x677b712d;
|
||||
|
||||
// bytes4(keccak256("InvalidApprovalSignatureError(bytes32,address)"))
|
||||
bytes4 internal constant INVALID_APPROVAL_SIGNATURE_ERROR_SELECTOR =
|
||||
0xd789b640;
|
||||
@ -74,21 +70,6 @@ library LibCoordinatorRichErrors {
|
||||
);
|
||||
}
|
||||
|
||||
function ApprovalExpiredError(
|
||||
bytes32 transactionHash,
|
||||
uint256 approvalExpirationTime
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
APPROVAL_EXPIRED_ERROR_SELECTOR,
|
||||
transactionHash,
|
||||
approvalExpirationTime
|
||||
);
|
||||
}
|
||||
|
||||
function InvalidApprovalSignatureError(
|
||||
bytes32 transactionHash,
|
||||
address approverAddress
|
||||
|
@ -11,7 +11,8 @@ import {
|
||||
import {
|
||||
blockchainTests,
|
||||
constants,
|
||||
getLatestBlockTimestampAsync,
|
||||
hexConcat,
|
||||
hexSlice,
|
||||
OrderFactory,
|
||||
TransactionFactory,
|
||||
} from '@0x/contracts-test-utils';
|
||||
@ -46,7 +47,7 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
let testFactory: CoordinatorTestFactory;
|
||||
|
||||
const GAS_PRICE = new BigNumber(env.txDefaults.gasPrice || constants.DEFAULT_GAS_PRICE);
|
||||
const PROTOCOL_FEE_MULTIPLIER = new BigNumber(150);
|
||||
const PROTOCOL_FEE_MULTIPLIER = new BigNumber(150000);
|
||||
const PROTOCOL_FEE = GAS_PRICE.times(PROTOCOL_FEE_MULTIPLIER);
|
||||
|
||||
before(async () => {
|
||||
@ -164,19 +165,12 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
const order = await orderFactory.newSignedOrderAsync();
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, [order]);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory.newSignedApproval(transaction, takerAddress);
|
||||
const txData = { from: takerAddress, value: PROTOCOL_FEE };
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
[order],
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
txData,
|
||||
);
|
||||
@ -191,7 +185,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
feeRecipientAddress,
|
||||
[],
|
||||
[],
|
||||
txData,
|
||||
);
|
||||
});
|
||||
@ -205,7 +198,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
feeRecipientAddress,
|
||||
[],
|
||||
[],
|
||||
txData,
|
||||
);
|
||||
});
|
||||
@ -219,7 +211,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
feeRecipientAddress,
|
||||
[],
|
||||
[],
|
||||
txData,
|
||||
);
|
||||
});
|
||||
@ -233,7 +224,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
feeRecipientAddress,
|
||||
[],
|
||||
[],
|
||||
txData,
|
||||
);
|
||||
});
|
||||
@ -247,7 +237,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
feeRecipientAddress,
|
||||
[],
|
||||
[],
|
||||
txData,
|
||||
);
|
||||
});
|
||||
@ -261,7 +250,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
takerAddress,
|
||||
[],
|
||||
[],
|
||||
{
|
||||
from: takerAddress,
|
||||
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
|
||||
@ -274,63 +262,31 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
const approval = approvalFactory.newSignedApproval(transaction, takerAddress);
|
||||
const signature = hexConcat(
|
||||
hexSlice(approval.signature, 0, 2),
|
||||
'0xFFFFFFFF',
|
||||
hexSlice(approval.signature, 6),
|
||||
);
|
||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[signature],
|
||||
{ from: takerAddress, value: PROTOCOL_FEE },
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, feeRecipientAddress),
|
||||
);
|
||||
});
|
||||
it(`${fnName} should revert with an expired approval`, async () => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: takerAddress, value: PROTOCOL_FEE },
|
||||
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||
);
|
||||
});
|
||||
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory.newSignedApproval(transaction, takerAddress);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: owner, value: PROTOCOL_FEE },
|
||||
new CoordinatorRevertErrors.InvalidOriginError(takerAddress),
|
||||
@ -344,18 +300,11 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory.newSignedApproval(transaction, takerAddress);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{
|
||||
from: takerAddress,
|
||||
@ -368,7 +317,7 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
await testFactory.executeFillTransactionTestAsync(orders, transaction, feeRecipientAddress, [], [], {
|
||||
await testFactory.executeFillTransactionTestAsync(orders, transaction, feeRecipientAddress, [], {
|
||||
from: feeRecipientAddress,
|
||||
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
|
||||
value: PROTOCOL_FEE.times(orders.length),
|
||||
@ -378,7 +327,7 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
await testFactory.executeFillTransactionTestAsync(orders, transaction, feeRecipientAddress, [], [], {
|
||||
await testFactory.executeFillTransactionTestAsync(orders, transaction, feeRecipientAddress, [], {
|
||||
from: feeRecipientAddress,
|
||||
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
|
||||
value: PROTOCOL_FEE.times(orders.length).plus(1),
|
||||
@ -388,63 +337,31 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
const approval = approvalFactory.newSignedApproval(transaction, takerAddress);
|
||||
const signature = hexConcat(
|
||||
hexSlice(approval.signature, 0, 2),
|
||||
'0xFFFFFFFF',
|
||||
hexSlice(approval.signature, 6),
|
||||
);
|
||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[signature],
|
||||
{ from: takerAddress, value: PROTOCOL_FEE.times(orders.length) },
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, feeRecipientAddress),
|
||||
);
|
||||
});
|
||||
it(`${fnName} should revert with an expired approval`, async () => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: takerAddress, value: PROTOCOL_FEE.times(orders.length) },
|
||||
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||
);
|
||||
});
|
||||
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory.newSignedApproval(
|
||||
transaction,
|
||||
takerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory.newSignedApproval(transaction, takerAddress);
|
||||
await testFactory.executeFillTransactionTestAsync(
|
||||
orders,
|
||||
transaction,
|
||||
takerAddress,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: owner, value: PROTOCOL_FEE.times(orders.length) },
|
||||
new CoordinatorRevertErrors.InvalidOriginError(takerAddress),
|
||||
@ -463,7 +380,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
makerAddress,
|
||||
[],
|
||||
[],
|
||||
{
|
||||
from: makerAddress,
|
||||
},
|
||||
@ -479,7 +395,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
makerAddress,
|
||||
[],
|
||||
[],
|
||||
{
|
||||
from: makerAddress,
|
||||
},
|
||||
@ -494,7 +409,6 @@ blockchainTests.resets('Coordinator tests', env => {
|
||||
transaction,
|
||||
makerAddress,
|
||||
[],
|
||||
[],
|
||||
{
|
||||
from: makerAddress,
|
||||
},
|
||||
|
@ -1,62 +1,77 @@
|
||||
import { blockchainTests, expect } from '@0x/contracts-test-utils';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
|
||||
import { CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src';
|
||||
|
||||
import { CoordinatorRegistryWrapper } from './utils/coordinator_registry_wrapper';
|
||||
import {
|
||||
artifacts,
|
||||
CoordinatorRegistryContract,
|
||||
CoordinatorRegistryCoordinatorEndpointSetEventArgs,
|
||||
CoordinatorTestFactory,
|
||||
} from '../src';
|
||||
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
blockchainTests.resets('Coordinator Registry tests', env => {
|
||||
let coordinatorRegistry: CoordinatorRegistryContract;
|
||||
let coordinatorOperator: string;
|
||||
const coordinatorEndpoint = 'http://sometec.0x.org';
|
||||
const nilCoordinatorEndpoint = '';
|
||||
let coordinatorRegistryWrapper: CoordinatorRegistryWrapper;
|
||||
// tests
|
||||
before(async () => {
|
||||
// setup accounts (skip owner)
|
||||
const accounts = await env.getAccountAddressesAsync();
|
||||
[, coordinatorOperator] = accounts;
|
||||
// deploy coordinator registry
|
||||
coordinatorRegistryWrapper = new CoordinatorRegistryWrapper(env.provider);
|
||||
await coordinatorRegistryWrapper.deployCoordinatorRegistryAsync();
|
||||
coordinatorRegistry = await CoordinatorRegistryContract.deployFrom0xArtifactAsync(
|
||||
artifacts.CoordinatorRegistry,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
});
|
||||
describe('core', () => {
|
||||
it('Should successfully set a Coordinator endpoint', async () => {
|
||||
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, coordinatorEndpoint);
|
||||
const recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
|
||||
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
|
||||
from: coordinatorOperator,
|
||||
});
|
||||
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
||||
coordinatorOperator,
|
||||
);
|
||||
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||
});
|
||||
it('Should successfully unset a Coordinator endpoint', async () => {
|
||||
// set Coordinator endpoint
|
||||
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, coordinatorEndpoint);
|
||||
let recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
|
||||
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(coordinatorEndpoint, {
|
||||
from: coordinatorOperator,
|
||||
});
|
||||
let recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
||||
coordinatorOperator,
|
||||
);
|
||||
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||
// unset Coordinator endpoint
|
||||
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, nilCoordinatorEndpoint);
|
||||
recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
|
||||
await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(nilCoordinatorEndpoint, {
|
||||
from: coordinatorOperator,
|
||||
});
|
||||
recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
||||
coordinatorOperator,
|
||||
);
|
||||
expect(recordedCoordinatorEndpoint).to.be.equal(nilCoordinatorEndpoint);
|
||||
});
|
||||
it('Should emit an event when setting Coordinator endpoint', async () => {
|
||||
// set Coordinator endpoint
|
||||
const txReceipt = await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(
|
||||
coordinatorOperator,
|
||||
const txReceipt = await coordinatorRegistry.setCoordinatorEndpoint.awaitTransactionSuccessAsync(
|
||||
coordinatorEndpoint,
|
||||
{
|
||||
from: coordinatorOperator,
|
||||
},
|
||||
);
|
||||
const recordedCoordinatorEndpoint = await coordinatorRegistryWrapper.getCoordinatorEndpointAsync(
|
||||
const recordedCoordinatorEndpoint = await coordinatorRegistry.getCoordinatorEndpoint.callAsync(
|
||||
coordinatorOperator,
|
||||
);
|
||||
expect(recordedCoordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||
// validate event
|
||||
expect(txReceipt.logs.length).to.be.equal(1);
|
||||
const log = txReceipt.logs[0] as LogWithDecodedArgs<CoordinatorRegistryCoordinatorEndpointSetEventArgs>;
|
||||
expect(log.args.coordinatorOperator).to.be.equal(coordinatorOperator);
|
||||
expect(log.args.coordinatorEndpoint).to.be.equal(coordinatorEndpoint);
|
||||
const expectedEvent: CoordinatorRegistryCoordinatorEndpointSetEventArgs = {
|
||||
coordinatorOperator,
|
||||
coordinatorEndpoint,
|
||||
};
|
||||
CoordinatorTestFactory.verifyEvents(txReceipt, [expectedEvent], 'CoordinatorEndpointSet');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -24,9 +24,9 @@ blockchainTests.resets('Libs tests', env => {
|
||||
describe('getApprovalHash', () => {
|
||||
it('should return the correct approval hash', async () => {
|
||||
const signedTx = {
|
||||
salt: new BigNumber(0),
|
||||
gasPrice: new BigNumber(0),
|
||||
expirationTimeSeconds: new BigNumber(0),
|
||||
salt: constants.ZERO_AMOUNT,
|
||||
gasPrice: constants.ZERO_AMOUNT,
|
||||
expirationTimeSeconds: constants.ZERO_AMOUNT,
|
||||
signerAddress: constants.NULL_ADDRESS,
|
||||
data: '0x1234',
|
||||
signature: '0x5678',
|
||||
@ -35,20 +35,13 @@ blockchainTests.resets('Libs tests', env => {
|
||||
chainId,
|
||||
},
|
||||
};
|
||||
const approvalExpirationTimeSeconds = new BigNumber(0);
|
||||
const txOrigin = constants.NULL_ADDRESS;
|
||||
const approval = {
|
||||
txOrigin,
|
||||
transactionHash: transactionHashUtils.getTransactionHashHex(signedTx),
|
||||
transactionSignature: signedTx.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
};
|
||||
const expectedApprovalHash = hashUtils.getApprovalHashHex(
|
||||
signedTx,
|
||||
coordinatorContract.address,
|
||||
txOrigin,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const expectedApprovalHash = hashUtils.getApprovalHashHex(signedTx, coordinatorContract.address, txOrigin);
|
||||
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash.callAsync(approval);
|
||||
expect(expectedApprovalHash).to.eq(approvalHash);
|
||||
});
|
||||
|
@ -3,14 +3,14 @@ import {
|
||||
blockchainTests,
|
||||
constants,
|
||||
expect,
|
||||
getLatestBlockTimestampAsync,
|
||||
hexConcat,
|
||||
hexSlice,
|
||||
randomAddress,
|
||||
TransactionFactory,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { CoordinatorRevertErrors, transactionHashUtils } from '@0x/order-utils';
|
||||
import { SignatureType, SignedOrder } from '@0x/types';
|
||||
import { BigNumber, LibBytesRevertErrors } from '@0x/utils';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
|
||||
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
|
||||
|
||||
@ -83,11 +83,10 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
it('should revert with with the Illegal signature type', async () => {
|
||||
const data = constants.NULL_BYTES;
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const illegalSignatureByte = ethUtil.toBuffer(SignatureType.Illegal).toString('hex');
|
||||
transaction.signature = `${transaction.signature.slice(
|
||||
0,
|
||||
transaction.signature.length - 2,
|
||||
)}${illegalSignatureByte}`;
|
||||
transaction.signature = hexConcat(
|
||||
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
|
||||
SignatureType.Illegal,
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||
new CoordinatorRevertErrors.SignatureError(
|
||||
@ -100,8 +99,7 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
it('should revert with with the Invalid signature type', async () => {
|
||||
const data = constants.NULL_BYTES;
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const invalidSignatureByte = ethUtil.toBuffer(SignatureType.Invalid).toString('hex');
|
||||
transaction.signature = `0x${invalidSignatureByte}`;
|
||||
transaction.signature = hexConcat(SignatureType.Invalid);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||
new CoordinatorRevertErrors.SignatureError(
|
||||
@ -111,14 +109,29 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
),
|
||||
);
|
||||
});
|
||||
it("should revert with with a signature type that doesn't exist", async () => {
|
||||
it('should revert with with a signature type that equals `NSignatureTypes`', async () => {
|
||||
const data = constants.NULL_BYTES;
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const invalidSignatureByte = '04';
|
||||
transaction.signature = `${transaction.signature.slice(
|
||||
0,
|
||||
transaction.signature.length - 2,
|
||||
)}${invalidSignatureByte}`;
|
||||
transaction.signature = hexConcat(
|
||||
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
|
||||
SignatureType.NSignatureTypes,
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||
new CoordinatorRevertErrors.SignatureError(
|
||||
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
),
|
||||
);
|
||||
});
|
||||
it("should revert with with a signature type that isn't supported", async () => {
|
||||
const data = constants.NULL_BYTES;
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
transaction.signature = hexConcat(
|
||||
hexSlice(transaction.signature, 0, transaction.signature.length - 1),
|
||||
SignatureType.Wallet,
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||
new CoordinatorRevertErrors.SignatureError(
|
||||
@ -215,27 +228,20 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
|
||||
describe('Single order approvals', () => {
|
||||
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) {
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1]`, async () => {
|
||||
const order = {
|
||||
...defaultOrder,
|
||||
senderAddress: constants.NULL_ADDRESS,
|
||||
@ -243,23 +249,16 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
const orders = [order];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
@ -268,33 +267,25 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{
|
||||
from: approvalSignerAddress1,
|
||||
},
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
@ -303,29 +294,25 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{
|
||||
from: approvalSignerAddress1,
|
||||
},
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
const signature = hexConcat(
|
||||
hexSlice(approval.signature, 0, 2),
|
||||
'0xFFFFFFFF',
|
||||
hexSlice(approval.signature, 6),
|
||||
);
|
||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
@ -335,48 +322,16 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
|
||||
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(tx).to.revertWith(
|
||||
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
);
|
||||
@ -390,50 +345,36 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
...exchangeConstants.MARKET_FILL_FN_NAMES,
|
||||
...exchangeConstants.MATCH_ORDER_FN_NAMES,
|
||||
]) {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder].map(order => ({
|
||||
...order,
|
||||
senderAddress: constants.NULL_ADDRESS,
|
||||
}));
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder].map(order => ({
|
||||
...order,
|
||||
senderAddress: constants.NULL_ADDRESS,
|
||||
@ -445,56 +386,37 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, senderAddress: constants.NULL_ADDRESS }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval1 = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval2 = approvalFactory2.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.signature, approval2.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
@ -503,33 +425,25 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval2 = approvalFactory2.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
||||
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.signature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
@ -538,7 +452,6 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
|
||||
@ -547,23 +460,20 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
const signature = hexConcat(
|
||||
hexSlice(approval.signature, 0, 2),
|
||||
'0xFFFFFFFF',
|
||||
hexSlice(approval.signature, 6),
|
||||
);
|
||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
@ -573,28 +483,21 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => {
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval1 = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
||||
const approvalSignature2 = hexConcat(
|
||||
hexSlice(approval2.signature, 0, 2),
|
||||
'0xFFFFFFFF',
|
||||
hexSlice(approval2.signature, 6),
|
||||
);
|
||||
const approval2 = approvalFactory2.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.signature, approvalSignature2],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
@ -604,23 +507,20 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress2),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval2 = approvalFactory2.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, transactionSignerAddress);
|
||||
const approvalSignature2 = hexConcat(
|
||||
hexSlice(approval2.signature, 0, 2),
|
||||
'0xFFFFFFFF',
|
||||
hexSlice(approval2.signature, 6),
|
||||
);
|
||||
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature2],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
@ -630,79 +530,16 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress2),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
|
||||
const approval1 = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds1,
|
||||
);
|
||||
const approval2 = approvalFactory2.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds2,
|
||||
);
|
||||
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
|
||||
[approval1.signature, approval2.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(tx).to.revertWith(
|
||||
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds2),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
|
||||
const approval2 = approvalFactory2.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.signature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
expect(tx).to.revertWith(
|
||||
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => {
|
||||
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
|
||||
const approval1 = approvalFactory1.newSignedApproval(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, transactionSignerAddress);
|
||||
|
||||
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval1.signature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
);
|
||||
@ -720,7 +557,6 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
@ -733,7 +569,6 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
@ -745,7 +580,6 @@ blockchainTests.resets('Mixins tests', env => {
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { signingUtils } from '@0x/contracts-test-utils';
|
||||
import { hexConcat, signingUtils } from '@0x/contracts-test-utils';
|
||||
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
|
||||
import { hashUtils, SignedCoordinatorApproval } from './index';
|
||||
|
||||
@ -17,21 +15,14 @@ export class ApprovalFactory {
|
||||
public newSignedApproval(
|
||||
transaction: SignedZeroExTransaction,
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber,
|
||||
signatureType: SignatureType = SignatureType.EthSign,
|
||||
): SignedCoordinatorApproval {
|
||||
const approvalHashBuff = hashUtils.getApprovalHashBuffer(
|
||||
transaction,
|
||||
this._verifyingContractAddress,
|
||||
txOrigin,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approvalHashBuff = hashUtils.getApprovalHashBuffer(transaction, this._verifyingContractAddress, txOrigin);
|
||||
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
|
||||
const signedApproval = {
|
||||
txOrigin,
|
||||
transaction,
|
||||
approvalExpirationTimeSeconds,
|
||||
signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),
|
||||
signature: hexConcat(signatureBuff),
|
||||
};
|
||||
return signedApproval;
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
|
||||
import { LogDecoder, txDefaults } from '@0x/contracts-test-utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
|
||||
|
||||
import { artifacts, CoordinatorRegistryContract } from '../../src';
|
||||
|
||||
export class CoordinatorRegistryWrapper {
|
||||
private readonly _web3Wrapper: Web3Wrapper;
|
||||
private readonly _provider: ZeroExProvider;
|
||||
private readonly _logDecoder: LogDecoder;
|
||||
private _coordinatorRegistryContract?: CoordinatorRegistryContract;
|
||||
/**
|
||||
* Instanitates an CoordinatorRegistryWrapper
|
||||
* @param provider Web3 provider to use for all JSON RPC requests
|
||||
* Instance of CoordinatorRegistryWrapper
|
||||
*/
|
||||
constructor(provider: ZeroExProvider) {
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._provider = provider;
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, { ...exchangeArtifacts, ...artifacts });
|
||||
}
|
||||
public async deployCoordinatorRegistryAsync(): Promise<CoordinatorRegistryContract> {
|
||||
this._coordinatorRegistryContract = await CoordinatorRegistryContract.deployFrom0xArtifactAsync(
|
||||
artifacts.CoordinatorRegistry,
|
||||
this._provider,
|
||||
txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
if (this._coordinatorRegistryContract === undefined) {
|
||||
throw new Error(`Failed to deploy Coordinator Registry contract.`);
|
||||
}
|
||||
return this._coordinatorRegistryContract;
|
||||
}
|
||||
public async setCoordinatorEndpointAsync(
|
||||
coordinatorOperator: string,
|
||||
coordinatorEndpoint: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
this._assertCoordinatorRegistryDeployed();
|
||||
const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(
|
||||
await (this
|
||||
._coordinatorRegistryContract as CoordinatorRegistryContract).setCoordinatorEndpoint.sendTransactionAsync(
|
||||
coordinatorEndpoint,
|
||||
{
|
||||
from: coordinatorOperator,
|
||||
},
|
||||
),
|
||||
);
|
||||
return txReceipt;
|
||||
}
|
||||
public async getCoordinatorEndpointAsync(coordinatorOperator: string): Promise<string> {
|
||||
this._assertCoordinatorRegistryDeployed();
|
||||
const coordinatorEndpoint = await (this
|
||||
._coordinatorRegistryContract as CoordinatorRegistryContract).getCoordinatorEndpoint.callAsync(
|
||||
coordinatorOperator,
|
||||
);
|
||||
return coordinatorEndpoint;
|
||||
}
|
||||
private _assertCoordinatorRegistryDeployed(): void {
|
||||
if (this._coordinatorRegistryContract === undefined) {
|
||||
throw new Error(
|
||||
'The Coordinator Registry contract was not deployed through the CoordinatorRegistryWrapper. Call `deployCoordinatorRegistryAsync` to deploy.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -71,7 +71,6 @@ export class CoordinatorTestFactory {
|
||||
orders: SignedOrder[],
|
||||
transaction: SignedZeroExTransaction,
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber[],
|
||||
approvalSignatures: string[],
|
||||
txData: Partial<TxData>,
|
||||
revertError?: RevertError,
|
||||
@ -81,7 +80,6 @@ export class CoordinatorTestFactory {
|
||||
transaction,
|
||||
txOrigin,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approvalSignatures,
|
||||
txData,
|
||||
);
|
||||
@ -106,7 +104,6 @@ export class CoordinatorTestFactory {
|
||||
orders: SignedOrder[],
|
||||
transaction: SignedZeroExTransaction,
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber[],
|
||||
approvalSignatures: string[],
|
||||
txData: Partial<TxData>,
|
||||
): Promise<void> {
|
||||
@ -114,7 +111,6 @@ export class CoordinatorTestFactory {
|
||||
transaction,
|
||||
txOrigin,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approvalSignatures,
|
||||
txData,
|
||||
);
|
||||
|
@ -1,33 +1,16 @@
|
||||
import { hexConcat } from '@0x/contracts-test-utils';
|
||||
import { eip712Utils } from '@0x/order-utils';
|
||||
import { SignedZeroExTransaction } from '@0x/types';
|
||||
import { BigNumber, signTypedDataUtils } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
import { signTypedDataUtils } from '@0x/utils';
|
||||
|
||||
export const hashUtils = {
|
||||
getApprovalHashBuffer(
|
||||
transaction: SignedZeroExTransaction,
|
||||
verifyingContract: string,
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber,
|
||||
): Buffer {
|
||||
const typedData = eip712Utils.createCoordinatorApprovalTypedData(
|
||||
transaction,
|
||||
verifyingContract,
|
||||
txOrigin,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
getApprovalHashBuffer(transaction: SignedZeroExTransaction, verifyingContract: string, txOrigin: string): Buffer {
|
||||
const typedData = eip712Utils.createCoordinatorApprovalTypedData(transaction, verifyingContract, txOrigin);
|
||||
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
|
||||
return hashBuffer;
|
||||
},
|
||||
getApprovalHashHex(
|
||||
transaction: SignedZeroExTransaction,
|
||||
verifyingContract: string,
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber,
|
||||
): string {
|
||||
const hashHex = `0x${hashUtils
|
||||
.getApprovalHashBuffer(transaction, verifyingContract, txOrigin, approvalExpirationTimeSeconds)
|
||||
.toString('hex')}`;
|
||||
getApprovalHashHex(transaction: SignedZeroExTransaction, verifyingContract: string, txOrigin: string): string {
|
||||
const hashHex = hexConcat(hashUtils.getApprovalHashBuffer(transaction, verifyingContract, txOrigin));
|
||||
return hashHex;
|
||||
},
|
||||
};
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { SignedZeroExTransaction } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
export interface CoordinatorApproval {
|
||||
transaction: SignedZeroExTransaction;
|
||||
txOrigin: string;
|
||||
approvalExpirationTimeSeconds: BigNumber;
|
||||
}
|
||||
|
||||
export interface SignedCoordinatorApproval extends CoordinatorApproval {
|
||||
|
@ -53,7 +53,10 @@ contract TestProtocolFeeCollector {
|
||||
payable
|
||||
{
|
||||
if (msg.value != protocolFeePaid) {
|
||||
assert(msg.value == 0);
|
||||
require(
|
||||
msg.value == 0,
|
||||
"No value should be forwarded to collector when paying fee in WETH"
|
||||
);
|
||||
|
||||
// Transfer the protocol fee to this address in WETH.
|
||||
IEtherToken(_wethAddress).transferFrom(
|
||||
|
@ -25,8 +25,8 @@
|
||||
"install:all": "yarn install",
|
||||
"wsrun": "wsrun",
|
||||
"lerna": "lerna",
|
||||
"build": "lerna link && wsrun build $PKG -r --stages --fast-exit --exclude-missing --exclude @0x/contracts-extensions --exclude @0x/contracts-coordinator",
|
||||
"build:ci": "lerna link && wsrun build:ci $PKG --fast-exit -r --stages --exclude-missing --exclude @0x/contracts-extensions --exclude @0x/contracts-coordinator",
|
||||
"build": "lerna link && wsrun build $PKG -r --stages --fast-exit --exclude-missing --exclude @0x/contracts-extensions",
|
||||
"build:ci": "lerna link && wsrun build:ci $PKG --fast-exit -r --stages --exclude-missing --exclude @0x/contracts-extensions",
|
||||
"build:contracts": "lerna link && wsrun build -p ${npm_package_config_contractsPackages} -c --fast-exit -r --stages --exclude-missing",
|
||||
"build:monorepo_scripts": "PKG=@0x/monorepo-scripts yarn build",
|
||||
"build:ts": "tsc -b",
|
||||
@ -51,7 +51,7 @@
|
||||
"lint:contracts": "wsrun lint -p ${npm_package_config_contractsPackages} -c --fast-exit --stages --exclude-missing"
|
||||
},
|
||||
"config": {
|
||||
"contractsPackages": "@0x/contracts-asset-proxy @0x/contracts-dev-utils @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-exchange-libs @0x/contracts-integrations @0x/contracts-multisig @0x/contracts-staking @0x/contracts-test-utils @0x/contracts-utils",
|
||||
"contractsPackages": "@0x/contracts-asset-proxy @0x/contracts-dev-utils @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-exchange-libs @0x/contracts-integrations @0x/contracts-multisig @0x/contracts-staking @0x/contracts-test-utils @0x/contracts-utils @0x/contracts-coordinator",
|
||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic",
|
||||
"packagesWithDocPages": "contract-wrappers 0x.js connect json-schemas subproviders web3-wrapper order-utils sol-compiler sol-coverage sol-profiler sol-trace ethereum-types asset-buyer asset-swapper migrations",
|
||||
"ignoreDependencyVersions": "@types/styled-components @types/node",
|
||||
|
@ -147,7 +147,6 @@ export const constants = {
|
||||
{ name: 'txOrigin', type: 'address' },
|
||||
{ name: 'transactionHash', type: 'bytes32' },
|
||||
{ name: 'transactionSignature', type: 'bytes' },
|
||||
{ name: 'approvalExpirationTimeSeconds', type: 'uint256' },
|
||||
],
|
||||
},
|
||||
ERC20_METHOD_ABI,
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
SignedZeroExTransaction,
|
||||
ZeroExTransaction,
|
||||
} from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { constants } from './constants';
|
||||
@ -99,14 +98,12 @@ export const eip712Utils = {
|
||||
* @param transaction A 0x transaction
|
||||
* @param verifyingContract The coordinator extension contract address that will be verifying the typedData
|
||||
* @param txOrigin The desired `tx.origin` that should be able to submit an Ethereum txn involving this 0x transaction
|
||||
* @param approvalExpirationTimeSeconds The approvals expiration time
|
||||
* @return A typed data object
|
||||
*/
|
||||
createCoordinatorApprovalTypedData: (
|
||||
transaction: SignedZeroExTransaction,
|
||||
verifyingContract: string,
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber,
|
||||
): EIP712TypedData => {
|
||||
const domain = {
|
||||
...transaction.domain,
|
||||
@ -119,7 +116,6 @@ export const eip712Utils = {
|
||||
txOrigin,
|
||||
transactionHash,
|
||||
transactionSignature: transaction.signature,
|
||||
approvalExpirationTimeSeconds: approvalExpirationTimeSeconds.toString(),
|
||||
};
|
||||
const typedData = eip712Utils.createTypedData(
|
||||
constants.COORDINATOR_APPROVAL_SCHEMA.name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user