Add txOrigin to approvals

This commit is contained in:
Amir Bandeali 2019-03-04 15:47:33 -08:00
parent 558ce4713c
commit 1136e58de7
12 changed files with 343 additions and 89 deletions

View File

@ -43,11 +43,13 @@ contract MixinCoordinatorApprovalVerifier is
/// @dev Validates that the 0x transaction has been approved by all of the feeRecipients /// @dev Validates that the 0x transaction has been approved by all of the feeRecipients
/// that correspond to each order in the transaction's Exchange calldata. /// that correspond to each order in the transaction's Exchange calldata.
/// @param transaction 0x transaction containing salt, signerAddress, and data. /// @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 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 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. /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.
function assertValidCoordinatorApprovals( function assertValidCoordinatorApprovals(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature, bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds, uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures bytes[] memory approvalSignatures
@ -64,6 +66,7 @@ contract MixinCoordinatorApprovalVerifier is
assertValidTransactionOrdersApproval( assertValidTransactionOrdersApproval(
transaction, transaction,
orders, orders,
txOrigin,
transactionSignature, transactionSignature,
approvalExpirationTimeSeconds, approvalExpirationTimeSeconds,
approvalSignatures approvalSignatures
@ -74,12 +77,14 @@ contract MixinCoordinatorApprovalVerifier is
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction. /// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
/// @param transaction 0x transaction containing salt, signerAddress, and data. /// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param orders Array of order structs containing order specifications. /// @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 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 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. /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
function assertValidTransactionOrdersApproval( function assertValidTransactionOrdersApproval(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
LibOrder.Order[] memory orders, LibOrder.Order[] memory orders,
address txOrigin,
bytes memory transactionSignature, bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds, uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures bytes[] memory approvalSignatures
@ -87,6 +92,12 @@ contract MixinCoordinatorApprovalVerifier is
public public
view view
{ {
// Verify that Ethereum tx signer is the same as the approved txOrigin
require(
tx.origin == txOrigin,
"INVALID_SENDER"
);
// Hash 0x transaction // Hash 0x transaction
bytes32 transactionHash = getTransactionHash(transaction); bytes32 transactionHash = getTransactionHash(transaction);
@ -98,6 +109,7 @@ contract MixinCoordinatorApprovalVerifier is
// Create approval message // Create approval message
uint256 currentApprovalExpirationTimeSeconds = approvalExpirationTimeSeconds[i]; uint256 currentApprovalExpirationTimeSeconds = approvalExpirationTimeSeconds[i];
CoordinatorApproval memory approval = CoordinatorApproval({ CoordinatorApproval memory approval = CoordinatorApproval({
txOrigin: txOrigin,
transactionHash: transactionHash, transactionHash: transactionHash,
transactionSignature: transactionSignature, transactionSignature: transactionSignature,
approvalExpirationTimeSeconds: currentApprovalExpirationTimeSeconds approvalExpirationTimeSeconds: currentApprovalExpirationTimeSeconds
@ -118,6 +130,9 @@ contract MixinCoordinatorApprovalVerifier is
approvalSignerAddresses = approvalSignerAddresses.append(approvalSignerAddress); approvalSignerAddresses = approvalSignerAddresses.append(approvalSignerAddress);
} }
// Ethereum transaction signer gives implicit signature of approval
approvalSignerAddresses = approvalSignerAddresses.append(tx.origin);
uint256 ordersLength = orders.length; uint256 ordersLength = orders.length;
for (uint256 i = 0; i < ordersLength; i++) { for (uint256 i = 0; i < ordersLength; i++) {
// Do not check approval if the order's senderAddress is null // Do not check approval if the order's senderAddress is null
@ -125,25 +140,13 @@ contract MixinCoordinatorApprovalVerifier is
continue; continue;
} }
// Ethereum transaction signer gives implicit signature of approval
address approverAddress = orders[i].feeRecipientAddress;
if (approverAddress == tx.origin) {
approvalSignerAddresses = approvalSignerAddresses.append(tx.origin);
continue;
}
// Ensure feeRecipient of order has approved this 0x transaction // Ensure feeRecipient of order has approved this 0x transaction
address approverAddress = orders[i].feeRecipientAddress;
bool isOrderApproved = approvalSignerAddresses.contains(approverAddress); bool isOrderApproved = approvalSignerAddresses.contains(approverAddress);
require( require(
isOrderApproved, isOrderApproved,
"INVALID_APPROVAL_SIGNATURE" "INVALID_APPROVAL_SIGNATURE"
); );
// The Ethereum transaction signer must be the 0x transaction signer or an approver of the 0x transaction
require(
transaction.signerAddress == tx.origin || approvalSignerAddresses.contains(tx.origin),
"INVALID_SENDER"
);
} }
} }

View File

@ -32,11 +32,13 @@ contract MixinCoordinatorCore is
{ {
/// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata. /// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata.
/// @param transaction 0x transaction containing salt, signerAddress, and data. /// @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 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 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. /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.
function executeTransaction( function executeTransaction(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature, bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds, uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures bytes[] memory approvalSignatures
@ -46,6 +48,7 @@ contract MixinCoordinatorCore is
// Validate that the 0x transaction has been approves by each feeRecipient // Validate that the 0x transaction has been approves by each feeRecipient
assertValidCoordinatorApprovals( assertValidCoordinatorApprovals(
transaction, transaction,
txOrigin,
transactionSignature, transactionSignature,
approvalExpirationTimeSeconds, approvalExpirationTimeSeconds,
approvalSignatures approvalSignatures

View File

@ -28,11 +28,13 @@ contract ICoordinatorApprovalVerifier {
/// @dev Validates that the 0x transaction has been approved by all of the feeRecipients /// @dev Validates that the 0x transaction has been approved by all of the feeRecipients
/// that correspond to each order in the transaction's Exchange calldata. /// that correspond to each order in the transaction's Exchange calldata.
/// @param transaction 0x transaction containing salt, signerAddress, and data. /// @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 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 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. /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.
function assertValidCoordinatorApprovals( function assertValidCoordinatorApprovals(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature, bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds, uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures bytes[] memory approvalSignatures
@ -43,12 +45,14 @@ contract ICoordinatorApprovalVerifier {
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction. /// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
/// @param transaction 0x transaction containing salt, signerAddress, and data. /// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @param orders Array of order structs containing order specifications. /// @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 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 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. /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
function assertValidTransactionOrdersApproval( function assertValidTransactionOrdersApproval(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
LibOrder.Order[] memory orders, LibOrder.Order[] memory orders,
address txOrigin,
bytes memory transactionSignature, bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds, uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures bytes[] memory approvalSignatures

View File

@ -26,11 +26,13 @@ contract ICoordinatorCore {
/// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata. /// @dev Executes a 0x transaction that has been signed by the feeRecipients that correspond to each order in the transaction's Exchange calldata.
/// @param transaction 0x transaction containing salt, signerAddress, and data. /// @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 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 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. /// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order in the transaction's Exchange calldata.
function executeTransaction( function executeTransaction(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
address txOrigin,
bytes memory transactionSignature, bytes memory transactionSignature,
uint256[] memory approvalExpirationTimeSeconds, uint256[] memory approvalExpirationTimeSeconds,
bytes[] memory approvalSignatures bytes[] memory approvalSignatures

View File

@ -27,14 +27,16 @@ contract LibCoordinatorApproval is
// Hash for the EIP712 Coordinator approval message // Hash for the EIP712 Coordinator approval message
// keccak256(abi.encodePacked( // keccak256(abi.encodePacked(
// "CoordinatorApproval(", // "CoordinatorApproval(",
// "address txOrigin,",
// "bytes32 transactionHash,", // "bytes32 transactionHash,",
// "bytes transactionSignature,", // "bytes transactionSignature,",
// "uint256 approvalExpirationTimeSeconds", // "uint256 approvalExpirationTimeSeconds",
// ")" // ")"
// )); // ));
bytes32 constant internal EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH = 0x9f6a55727f39e17015e248e6457fbf0b18270e56c53093ff432d3db5703e191e; bytes32 constant internal EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH = 0x2fbcdbaa76bc7589916958ae919dfbef04d23f6bbf26de6ff317b32c6cc01e05;
struct CoordinatorApproval { struct CoordinatorApproval {
address txOrigin; // Required signer of Ethereum transaction that is submitting approval.
bytes32 transactionHash; // EIP712 hash of the transaction, using the domain separator of this contract. bytes32 transactionHash; // EIP712 hash of the transaction, using the domain separator of this contract.
bytes transactionSignature; // Signature of the 0x transaction. bytes transactionSignature; // Signature of the 0x transaction.
uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the signature expires. uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the signature expires.
@ -62,6 +64,7 @@ contract LibCoordinatorApproval is
{ {
bytes32 schemaHash = EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH; bytes32 schemaHash = EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH;
bytes memory transactionSignature = approval.transactionSignature; bytes memory transactionSignature = approval.transactionSignature;
address txOrigin = approval.txOrigin;
bytes32 transactionHash = approval.transactionHash; bytes32 transactionHash = approval.transactionHash;
uint256 approvalExpirationTimeSeconds = approval.approvalExpirationTimeSeconds; uint256 approvalExpirationTimeSeconds = approval.approvalExpirationTimeSeconds;
@ -80,12 +83,13 @@ contract LibCoordinatorApproval is
// Load free memory pointer // Load free memory pointer
let memPtr := mload(64) let memPtr := mload(64)
mstore(memPtr, schemaHash) // hash of schema mstore(memPtr, schemaHash) // hash of schema
mstore(add(memPtr, 32), transactionHash) // transactionHash mstore(add(memPtr, 32), txOrigin) // txOrigin
mstore(add(memPtr, 64), transactionSignatureHash) // transactionSignatureHash mstore(add(memPtr, 64), transactionHash) // transactionHash
mstore(add(memPtr, 96), approvalExpirationTimeSeconds) // approvalExpirationTimeSeconds mstore(add(memPtr, 96), transactionSignatureHash) // transactionSignatureHash
mstore(add(memPtr, 128), approvalExpirationTimeSeconds) // approvalExpirationTimeSeconds
// Compute hash // Compute hash
result := keccak256(memPtr, 128) result := keccak256(memPtr, 160)
} }
return result; return result;
} }

View File

@ -126,10 +126,15 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -161,6 +166,7 @@ describe('Coordinator tests', () => {
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
feeRecipientAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
@ -192,6 +198,7 @@ describe('Coordinator tests', () => {
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
@ -209,11 +216,16 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`; const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[signature], [signature],
@ -228,10 +240,15 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -246,10 +263,15 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -268,10 +290,15 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -305,6 +332,7 @@ describe('Coordinator tests', () => {
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
feeRecipientAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
@ -337,11 +365,16 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`; const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[signature], [signature],
@ -356,10 +389,15 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -374,10 +412,15 @@ describe('Coordinator tests', () => {
const transaction = takerTransactionFactory.newSignedTransaction(data); const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory.newSignedApproval(
transaction,
takerAddress,
approvalExpirationTimeSeconds,
);
await expectTransactionFailedAsync( await expectTransactionFailedAsync(
coordinatorContract.executeTransaction.sendTransactionAsync( coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
takerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -396,6 +439,7 @@ describe('Coordinator tests', () => {
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
makerAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
@ -423,6 +467,7 @@ describe('Coordinator tests', () => {
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
makerAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
@ -452,6 +497,7 @@ describe('Coordinator tests', () => {
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync( const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await coordinatorContract.executeTransaction.sendTransactionAsync( await coordinatorContract.executeTransaction.sendTransactionAsync(
transaction, transaction,
makerAddress,
transaction.signature, transaction.signature,
[], [],
[], [],

View File

@ -52,12 +52,18 @@ describe('Libs tests', () => {
signature: '0x5678', signature: '0x5678',
}; };
const approvalExpirationTimeSeconds = new BigNumber(0); const approvalExpirationTimeSeconds = new BigNumber(0);
const txOrigin = constants.NULL_ADDRESS;
const approval = { const approval = {
txOrigin,
transactionHash: hashUtils.getTransactionHashHex(signedTx), transactionHash: hashUtils.getTransactionHashHex(signedTx),
transactionSignature: signedTx.signature, transactionSignature: signedTx.signature,
approvalExpirationTimeSeconds, approvalExpirationTimeSeconds,
}; };
const expectedApprovalHash = hashUtils.getApprovalHashHex(signedTx, approvalExpirationTimeSeconds); const expectedApprovalHash = hashUtils.getApprovalHashHex(
signedTx,
txOrigin,
approvalExpirationTimeSeconds,
);
const approvalHash = await testLibs.publicGetCoordinatorApprovalHash.callAsync(approval); const approvalHash = await testLibs.publicGetCoordinatorApprovalHash.callAsync(approval);
expect(expectedApprovalHash).to.eq(approvalHash); expect(expectedApprovalHash).to.eq(approvalHash);
}); });

View File

@ -137,10 +137,15 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -148,6 +153,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -164,10 +170,15 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -175,6 +186,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -188,14 +200,22 @@ describe('Mixins tests', () => {
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[], [],
[], [],
{ from: approvalSignerAddress1 }, { from: approvalSignerAddress1 },
); );
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], { await mixins.assertValidCoordinatorApprovals.callAsync(
from: approvalSignerAddress1, transaction,
}); 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], expiration=[invalid]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
@ -203,10 +223,15 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -214,6 +239,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -227,14 +253,22 @@ describe('Mixins tests', () => {
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[], [],
[], [],
{ from: approvalSignerAddress1 }, { from: approvalSignerAddress1 },
); );
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], { await mixins.assertValidCoordinatorApprovals.callAsync(
from: approvalSignerAddress1, transaction,
}); 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], expiration=[valid]`, async () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
@ -242,12 +276,17 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`; const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[signature], [signature],
@ -258,6 +297,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[signature], [signature],
@ -272,11 +312,16 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -287,6 +332,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -301,11 +347,16 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -316,6 +367,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -338,10 +390,15 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -349,6 +406,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -364,10 +422,15 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -375,6 +438,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -391,14 +455,20 @@ describe('Mixins tests', () => {
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
{ from: transactionSignerAddress }, { from: transactionSignerAddress },
); );
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, 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], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, senderAddress: devConstants.NULL_ADDRESS }]; const orders = [defaultOrder, { ...defaultOrder, senderAddress: devConstants.NULL_ADDRESS }];
@ -406,10 +476,15 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -417,6 +492,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval.signature], [approval.signature],
@ -429,11 +505,20 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval1 = approvalFactory1.newSignedApproval(
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds); transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approval2.signature], [approval1.signature, approval2.signature],
@ -441,6 +526,7 @@ describe('Mixins tests', () => {
); );
await mixins.assertValidCoordinatorApprovals.callAsync( await mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approval2.signature], [approval1.signature, approval2.signature],
@ -454,36 +540,54 @@ describe('Mixins tests', () => {
await mixins.assertValidTransactionOrdersApproval.callAsync( await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
approvalSignerAddress1,
transaction.signature,
[],
[],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[], [],
[], [],
{ from: approvalSignerAddress1 }, { from: approvalSignerAddress1 },
); );
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], {
from: approvalSignerAddress1,
});
}); });
it(`Should be successful: 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], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval2 = approvalFactory2.newSignedApproval(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, transactionSignerAddress,
transaction.signature, approvalExpirationTimeSeconds,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
); );
await mixins.assertValidCoordinatorApprovals.callAsync( expectContractCallFailedAsync(
transaction, mixins.assertValidTransactionOrdersApproval.callAsync(
transaction.signature, transaction,
[approvalExpirationTimeSeconds], orders,
[approval2.signature], transactionSignerAddress,
{ from: approvalSignerAddress1 }, transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidSender,
);
expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidSender,
); );
}); });
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=[], expiration=[]`, async () => {
@ -494,6 +598,7 @@ describe('Mixins tests', () => {
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[], [],
[], [],
@ -502,9 +607,14 @@ describe('Mixins tests', () => {
RevertReason.InvalidApprovalSignature, RevertReason.InvalidApprovalSignature,
); );
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], { mixins.assertValidCoordinatorApprovals.callAsync(
from: transactionSignerAddress, transaction,
}), transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature, RevertReason.InvalidApprovalSignature,
); );
}); });
@ -514,12 +624,17 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`; const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[signature], [signature],
@ -530,6 +645,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[signature], [signature],
@ -544,13 +660,22 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval1 = approvalFactory1.newSignedApproval(
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds); transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`; const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approvalSignature2], [approval1.signature, approvalSignature2],
@ -561,6 +686,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.signature, approvalSignature2], [approval1.signature, approvalSignature2],
@ -575,12 +701,17 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`; const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approvalSignature2], [approvalSignature2],
@ -591,6 +722,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approvalSignature2], [approvalSignature2],
@ -606,12 +738,21 @@ describe('Mixins tests', () => {
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds1); const approval1 = approvalFactory1.newSignedApproval(
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds2); transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds1,
);
const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds2,
);
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2], [approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.signature, approval2.signature], [approval1.signature, approval2.signature],
@ -622,6 +763,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2], [approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.signature, approval2.signature], [approval1.signature, approval2.signature],
@ -636,11 +778,16 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval2 = approvalFactory2.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval2.signature], [approval2.signature],
@ -651,6 +798,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
approvalSignerAddress1,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval2.signature], [approval2.signature],
@ -665,11 +813,16 @@ describe('Mixins tests', () => {
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds); const approval1 = approvalFactory1.newSignedApproval(
transaction,
transactionSignerAddress,
approvalExpirationTimeSeconds,
);
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync( mixins.assertValidTransactionOrdersApproval.callAsync(
transaction, transaction,
orders, orders,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval1.signature], [approval1.signature],
@ -680,6 +833,7 @@ describe('Mixins tests', () => {
expectContractCallFailedAsync( expectContractCallFailedAsync(
mixins.assertValidCoordinatorApprovals.callAsync( mixins.assertValidCoordinatorApprovals.callAsync(
transaction, transaction,
transactionSignerAddress,
transaction.signature, transaction.signature,
[approvalExpirationTimeSeconds], [approvalExpirationTimeSeconds],
[approval1.signature], [approval1.signature],
@ -695,25 +849,40 @@ describe('Mixins tests', () => {
const orders = [defaultOrder]; const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], { await mixins.assertValidCoordinatorApprovals.callAsync(
from: transactionSignerAddress, transaction,
}); transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
}); });
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => { it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
const orders = [defaultOrder, defaultOrder]; const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], { await mixins.assertValidCoordinatorApprovals.callAsync(
from: transactionSignerAddress, transaction,
}); transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
}); });
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => { it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
const orders: SignedOrder[] = []; const orders: SignedOrder[] = [];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders); const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data); const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(transaction, transaction.signature, [], [], { await mixins.assertValidCoordinatorApprovals.callAsync(
from: transactionSignerAddress, transaction,
}); transactionSignerAddress,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
);
}); });
}); });
}); });

View File

@ -13,6 +13,7 @@ export class ApprovalFactory {
} }
public newSignedApproval( public newSignedApproval(
transaction: SignedZeroExTransaction, transaction: SignedZeroExTransaction,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber, approvalExpirationTimeSeconds: BigNumber,
signatureType: CoordinatorSignatureType = CoordinatorSignatureType.EthSign, signatureType: CoordinatorSignatureType = CoordinatorSignatureType.EthSign,
): SignedCoordinatorApproval { ): SignedCoordinatorApproval {
@ -20,9 +21,14 @@ export class ApprovalFactory {
...transaction, ...transaction,
verifyingContractAddress: this._verifyingContractAddress, verifyingContractAddress: this._verifyingContractAddress,
}; };
const approvalHashBuff = hashUtils.getApprovalHashBuffer(coordinatorTransaction, approvalExpirationTimeSeconds); const approvalHashBuff = hashUtils.getApprovalHashBuffer(
coordinatorTransaction,
txOrigin,
approvalExpirationTimeSeconds,
);
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType); const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
const signedApproval = { const signedApproval = {
txOrigin,
transaction: coordinatorTransaction, transaction: coordinatorTransaction,
approvalExpirationTimeSeconds, approvalExpirationTimeSeconds,
signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')), signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),

View File

@ -6,6 +6,7 @@ export const constants = {
COORDINATOR_APPROVAL_SCHEMA: { COORDINATOR_APPROVAL_SCHEMA: {
name: 'CoordinatorApproval', name: 'CoordinatorApproval',
parameters: [ parameters: [
{ name: 'txOrigin', type: 'address' },
{ name: 'transactionHash', type: 'bytes32' }, { name: 'transactionHash', type: 'bytes32' },
{ name: 'transactionSignature', type: 'bytes' }, { name: 'transactionSignature', type: 'bytes' },
{ name: 'approvalExpirationTimeSeconds', type: 'uint256' }, { name: 'approvalExpirationTimeSeconds', type: 'uint256' },

View File

@ -7,7 +7,11 @@ import * as _ from 'lodash';
import { constants } from './index'; import { constants } from './index';
export const hashUtils = { export const hashUtils = {
getApprovalHashBuffer(transaction: SignedZeroExTransaction, approvalExpirationTimeSeconds: BigNumber): Buffer { getApprovalHashBuffer(
transaction: SignedZeroExTransaction,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): Buffer {
const domain = { const domain = {
name: constants.COORDINATOR_DOMAIN_NAME, name: constants.COORDINATOR_DOMAIN_NAME,
version: constants.COORDINATOR_DOMAIN_VERSION, version: constants.COORDINATOR_DOMAIN_VERSION,
@ -15,6 +19,7 @@ export const hashUtils = {
}; };
const transactionHash = hashUtils.getTransactionHashHex(transaction); const transactionHash = hashUtils.getTransactionHashHex(transaction);
const approval = { const approval = {
txOrigin,
transactionHash, transactionHash,
transactionSignature: transaction.signature, transactionSignature: transaction.signature,
approvalExpirationTimeSeconds: approvalExpirationTimeSeconds.toString(), approvalExpirationTimeSeconds: approvalExpirationTimeSeconds.toString(),
@ -30,9 +35,13 @@ export const hashUtils = {
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData); const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
return hashBuffer; return hashBuffer;
}, },
getApprovalHashHex(transaction: SignedZeroExTransaction, approvalExpirationTimeSeconds: BigNumber): string { getApprovalHashHex(
transaction: SignedZeroExTransaction,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): string {
const hashHex = `0x${hashUtils const hashHex = `0x${hashUtils
.getApprovalHashBuffer(transaction, approvalExpirationTimeSeconds) .getApprovalHashBuffer(transaction, txOrigin, approvalExpirationTimeSeconds)
.toString('hex')}`; .toString('hex')}`;
return hashHex; return hashHex;
}, },

View File

@ -3,6 +3,7 @@ import { BigNumber } from '@0x/utils';
export interface CoordinatorApproval { export interface CoordinatorApproval {
transaction: SignedZeroExTransaction; transaction: SignedZeroExTransaction;
txOrigin: string;
approvalExpirationTimeSeconds: BigNumber; approvalExpirationTimeSeconds: BigNumber;
} }