173 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { blockchainTests, expect } from '@0x/contracts-test-utils';
 | |
| import { AuthorizableRevertErrors } from '@0x/contracts-utils';
 | |
| import { StakingRevertErrors } from '@0x/utils';
 | |
| import { LogWithDecodedArgs, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | |
| 
 | |
| import { artifacts } from '../artifacts';
 | |
| import {
 | |
|     TestExchangeManagerContract,
 | |
|     TestExchangeManagerExchangeAddedEventArgs,
 | |
|     TestExchangeManagerExchangeRemovedEventArgs,
 | |
| } from '../wrappers';
 | |
| 
 | |
| blockchainTests.resets('Exchange Unit Tests', env => {
 | |
|     // Addresses
 | |
|     let nonOwner: string;
 | |
|     let owner: string;
 | |
|     let nonExchange: string;
 | |
|     let exchange: string;
 | |
|     let nonAuthority: string;
 | |
|     let authority: string;
 | |
| 
 | |
|     // Exchange Manager
 | |
|     let exchangeManager: TestExchangeManagerContract;
 | |
| 
 | |
|     before(async () => {
 | |
|         // Set up addresses for testing.
 | |
|         [nonOwner, owner, nonExchange, exchange, nonAuthority, authority] = await env.getAccountAddressesAsync();
 | |
| 
 | |
|         // Deploy the Exchange Manager contract.
 | |
|         exchangeManager = await TestExchangeManagerContract.deployFrom0xArtifactAsync(
 | |
|             artifacts.TestExchangeManager,
 | |
|             env.provider,
 | |
|             {
 | |
|                 ...env.txDefaults,
 | |
|                 from: owner,
 | |
|             },
 | |
|             artifacts,
 | |
|         );
 | |
| 
 | |
|         // Register the exchange.
 | |
|         await exchangeManager.setValidExchange(exchange).awaitTransactionSuccessAsync();
 | |
| 
 | |
|         // Register an authority.
 | |
|         await exchangeManager.addAuthorizedAddress(authority).awaitTransactionSuccessAsync({ from: owner });
 | |
|     });
 | |
| 
 | |
|     describe('onlyExchange', () => {
 | |
|         it('should revert if called by an unregistered exchange', async () => {
 | |
|             const expectedError = new StakingRevertErrors.OnlyCallableByExchangeError(nonExchange);
 | |
|             return expect(exchangeManager.onlyExchangeFunction().callAsync({ from: nonExchange })).to.revertWith(
 | |
|                 expectedError,
 | |
|             );
 | |
|         });
 | |
| 
 | |
|         it('should succeed if called by a registered exchange', async () => {
 | |
|             const didSucceed = await exchangeManager.onlyExchangeFunction().callAsync({ from: exchange });
 | |
|             expect(didSucceed).to.be.true();
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     enum ExchangeManagerEventType {
 | |
|         ExchangeAdded,
 | |
|         ExchangeRemoved,
 | |
|     }
 | |
| 
 | |
|     // Verify the logs emitted by `addExchangeAddress` and `removeExchangeAddress`
 | |
|     function verifyExchangeManagerEvent(
 | |
|         eventType: ExchangeManagerEventType,
 | |
|         exchangeAddress: string,
 | |
|         receipt: TransactionReceiptWithDecodedLogs,
 | |
|     ): void {
 | |
|         // Ensure that the length of the logs is correct.
 | |
|         expect(receipt.logs.length).to.be.eq(1);
 | |
| 
 | |
|         // Ensure that the event emitted was correct.
 | |
|         let log;
 | |
|         // tslint:disable:no-unnecessary-type-assertion
 | |
|         if (eventType === ExchangeManagerEventType.ExchangeAdded) {
 | |
|             log = receipt.logs[0] as LogWithDecodedArgs<TestExchangeManagerExchangeAddedEventArgs>;
 | |
|             expect(log.event).to.be.eq('ExchangeAdded');
 | |
|         } else {
 | |
|             log = receipt.logs[0] as LogWithDecodedArgs<TestExchangeManagerExchangeRemovedEventArgs>;
 | |
|             expect(log.event).to.be.eq('ExchangeRemoved');
 | |
|         }
 | |
|         // tslint:enable:no-unnecessary-type-assertion
 | |
|         expect(log.args.exchangeAddress).to.be.eq(exchangeAddress);
 | |
|     }
 | |
| 
 | |
|     describe('addExchangeAddress', () => {
 | |
|         it('should revert if called by an unauthorized address', async () => {
 | |
|             const expectedError = new AuthorizableRevertErrors.SenderNotAuthorizedError(nonAuthority);
 | |
|             const tx = exchangeManager.addExchangeAddress(nonExchange).awaitTransactionSuccessAsync({
 | |
|                 from: nonAuthority,
 | |
|             });
 | |
|             return expect(tx).to.revertWith(expectedError);
 | |
|         });
 | |
| 
 | |
|         it('should revert when adding an exchange if called by the (non-authorized) owner', async () => {
 | |
|             const expectedError = new AuthorizableRevertErrors.SenderNotAuthorizedError(owner);
 | |
|             const tx = exchangeManager.addExchangeAddress(nonExchange).awaitTransactionSuccessAsync({
 | |
|                 from: owner,
 | |
|             });
 | |
|             return expect(tx).to.revertWith(expectedError);
 | |
|         });
 | |
| 
 | |
|         it('should successfully add an exchange if called by an authorized address', async () => {
 | |
|             // Register a new exchange.
 | |
|             const receipt = await exchangeManager.addExchangeAddress(nonExchange).awaitTransactionSuccessAsync({
 | |
|                 from: authority,
 | |
|             });
 | |
| 
 | |
|             // Ensure that the logged event was correct.
 | |
|             verifyExchangeManagerEvent(ExchangeManagerEventType.ExchangeAdded, nonExchange, receipt);
 | |
| 
 | |
|             // Ensure that the exchange was successfully registered.
 | |
|             const isValidExchange = await exchangeManager.validExchanges(nonExchange).callAsync();
 | |
|             expect(isValidExchange).to.be.true();
 | |
|         });
 | |
| 
 | |
|         it('should fail to add an exchange redundantly', async () => {
 | |
|             const expectedError = new StakingRevertErrors.ExchangeManagerError(
 | |
|                 StakingRevertErrors.ExchangeManagerErrorCodes.ExchangeAlreadyRegistered,
 | |
|                 exchange,
 | |
|             );
 | |
|             const tx = exchangeManager.addExchangeAddress(exchange).awaitTransactionSuccessAsync({ from: authority });
 | |
|             return expect(tx).to.revertWith(expectedError);
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     describe('removeExchangeAddress', () => {
 | |
|         it('should revert if called by an unauthorized address', async () => {
 | |
|             const expectedError = new AuthorizableRevertErrors.SenderNotAuthorizedError(nonAuthority);
 | |
|             const tx = exchangeManager.removeExchangeAddress(exchange).awaitTransactionSuccessAsync({
 | |
|                 from: nonAuthority,
 | |
|             });
 | |
|             return expect(tx).to.revertWith(expectedError);
 | |
|         });
 | |
| 
 | |
|         it('should revert when removing an exchange if called by the (non-authorized) owner', async () => {
 | |
|             const expectedError = new AuthorizableRevertErrors.SenderNotAuthorizedError(owner);
 | |
|             const tx = exchangeManager.removeExchangeAddress(nonExchange).awaitTransactionSuccessAsync({
 | |
|                 from: owner,
 | |
|             });
 | |
|             return expect(tx).to.revertWith(expectedError);
 | |
|         });
 | |
| 
 | |
|         it('should successfully remove a registered exchange if called by an authorized address', async () => {
 | |
|             // Remove the registered exchange.
 | |
|             const receipt = await exchangeManager.removeExchangeAddress(exchange).awaitTransactionSuccessAsync({
 | |
|                 from: authority,
 | |
|             });
 | |
| 
 | |
|             // Ensure that the logged event was correct.
 | |
|             verifyExchangeManagerEvent(ExchangeManagerEventType.ExchangeRemoved, exchange, receipt);
 | |
| 
 | |
|             // Ensure that the exchange was removed.
 | |
|             const isValidExchange = await exchangeManager.validExchanges(exchange).callAsync();
 | |
|             expect(isValidExchange).to.be.false();
 | |
|         });
 | |
| 
 | |
|         it('should fail to remove an exchange redundantly', async () => {
 | |
|             const expectedError = new StakingRevertErrors.ExchangeManagerError(
 | |
|                 StakingRevertErrors.ExchangeManagerErrorCodes.ExchangeNotRegistered,
 | |
|                 nonExchange,
 | |
|             );
 | |
|             const tx = exchangeManager.removeExchangeAddress(nonExchange).awaitTransactionSuccessAsync({
 | |
|                 from: authority,
 | |
|             });
 | |
|             return expect(tx).to.revertWith(expectedError);
 | |
|         });
 | |
|     });
 | |
| });
 |