aboutsummaryrefslogblamecommitdiffstats
path: root/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
blob: 62aa625fedb08ea54ac3c7b3c60073e9053b16bc (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11


                                                                                        







                                                                                                                 





                                                                                             



































































































































                                                                                                                      
   
import * as chai from 'chai';

import * as tokenTransferProxyJSON from '../../build/contracts/TokenTransferProxy.json';
import { Artifacts } from '../../util/artifacts';
import { constants } from '../../util/constants';
import { crypto } from '../../util/crypto';
import { MultiSigWrapper } from '../../util/multi_sig_wrapper';
import { ContractInstance, TransactionDataParams } from '../../util/types';

import { chaiSetup } from './utils/chai_setup';
const { TokenTransferProxy, MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress } = new Artifacts(artifacts);
const PROXY_ABI = (tokenTransferProxyJSON as any).abi;

chaiSetup.configure();
const expect = chai.expect;

contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: string[]) => {
    const owners = [accounts[0], accounts[1]];
    const requiredApprovals = 2;
    const SECONDS_TIME_LOCKED = 1000000;

    // initialize fake addresses
    const authorizedAddress = `0x${crypto
        .solSHA3([accounts[0]])
        .slice(0, 20)
        .toString('hex')}`;
    const unauthorizedAddress = `0x${crypto
        .solSHA3([accounts[1]])
        .slice(0, 20)
        .toString('hex')}`;

    let tokenTransferProxy: ContractInstance;
    let multiSig: ContractInstance;
    let multiSigWrapper: MultiSigWrapper;

    let validDestination: string;

    beforeEach(async () => {
        const initialOwner = accounts[0];
        tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
        await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {
            from: initialOwner,
        });
        multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
            owners,
            requiredApprovals,
            SECONDS_TIME_LOCKED,
            tokenTransferProxy.address,
        );
        await tokenTransferProxy.transferOwnership(multiSig.address, {
            from: initialOwner,
        });
        multiSigWrapper = new MultiSigWrapper(multiSig);
        validDestination = tokenTransferProxy.address;
    });

    describe('isFunctionRemoveAuthorizedAddress', () => {
        it('should throw if data is not for removeAuthorizedAddress', async () => {
            const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
            return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT);
        });

        it('should return true if data is for removeAuthorizedAddress', async () => {
            const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]);
            const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data);
            expect(isFunctionRemoveAuthorizedAddress).to.be.true();
        });
    });

    describe('executeRemoveAuthorizedAddress', () => {
        it('should throw without the required confirmations', async () => {
            const dataParams: TransactionDataParams = {
                name: 'removeAuthorizedAddress',
                abi: PROXY_ABI,
                args: [authorizedAddress],
            };
            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
            const txId = res.logs[0].args.transactionId.toString();

            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
        });

        it('should throw if tx destination is not the tokenTransferProxy', async () => {
            const invalidTokenTransferProxy = await TokenTransferProxy.new();
            const invalidDestination = invalidTokenTransferProxy.address;
            const dataParams: TransactionDataParams = {
                name: 'removeAuthorizedAddress',
                abi: PROXY_ABI,
                args: [authorizedAddress],
            };
            const res = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams);
            const txId = res.logs[0].args.transactionId.toString();
            await multiSig.confirmTransaction(txId, { from: owners[1] });
            const isConfirmed = await multiSig.isConfirmed.call(txId);
            expect(isConfirmed).to.be.true();

            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
        });

        it('should throw if tx data is not for removeAuthorizedAddress', async () => {
            const dataParams: TransactionDataParams = {
                name: 'addAuthorizedAddress',
                abi: PROXY_ABI,
                args: [unauthorizedAddress],
            };
            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
            const txId = res.logs[0].args.transactionId.toString();
            await multiSig.confirmTransaction(txId, { from: owners[1] });
            const isConfirmed = await multiSig.isConfirmed.call(txId);
            expect(isConfirmed).to.be.true();

            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
        });

        it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => {
            const dataParams: TransactionDataParams = {
                name: 'removeAuthorizedAddress',
                abi: PROXY_ABI,
                args: [authorizedAddress],
            };
            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
            const txId = res.logs[0].args.transactionId.toString();
            await multiSig.confirmTransaction(txId, { from: owners[1] });
            const isConfirmed = await multiSig.isConfirmed.call(txId);
            expect(isConfirmed).to.be.true();
            await multiSig.executeRemoveAuthorizedAddress(txId);

            const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress);
            expect(isAuthorized).to.be.false();
        });

        it('should throw if already executed', async () => {
            const dataParams: TransactionDataParams = {
                name: 'removeAuthorizedAddress',
                abi: PROXY_ABI,
                args: [authorizedAddress],
            };
            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
            const txId = res.logs[0].args.transactionId.toString();
            await multiSig.confirmTransaction(txId, { from: owners[1] });
            const isConfirmed = await multiSig.isConfirmed.call(txId);
            expect(isConfirmed).to.be.true();
            await multiSig.executeRemoveAuthorizedAddress(txId);
            const tx = await multiSig.transactions.call(txId);
            const isExecuted = tx[3];
            expect(isExecuted).to.be.true();
            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
        });
    });
});