<|start_filename|>erc777/migrations/2_deploy_contracts.js<|end_filename|>
const erc777 = artifacts.require('erc777');

// NOTE: this address has to match the 'from' address used in 'truffle.js'
const truffleFromAddress = '0x954e72fdc51Cf919203067406fB337Ed4bDC8CdA';

const args = {
  name: 'My777Token',
  symbol: 'MT777',
  totalSupply: 100000000,
  granularity: 1,
  defaultOperators: [
    truffleFromAddress,
    '0x0000000000000000000000000000000000000001',
    '0x0000000000000000000000000000000000000002',
    '0x0000000000000000000000000000000000000003',
  ],
}

module.exports = function(deployer) {
  deployer.deploy(
    erc777,
    args.name,
    args.symbol,
    args.totalSupply,
    args.granularity,
    args.defaultOperators
  );
};


<|start_filename|>linear_optimization_problem_bounty/test/linear_optimization_problem_bounty.js<|end_filename|>
const LOPB = artifacts.require("linear_optimization_problem_bounty");

const args = {
  durationInBlocks: 10,
}

contract("linear_optimization_problem_bounty", async accounts => {
  it("...should set correct initial paramters.", async () => {
    const instance = await LOPB.deployed({ ...args });
    const owner = await instance.owner();
    const bestSolution = await instance.bestSolution();
    const durationInBlocks = await instance.durationInBlocks();
    const competitionEnd = await instance.competitionEnd();
    const addressOfWinner = await instance.addressOfWinner();
    const claimPeriodeLength = await instance.claimPeriodeLength();

    const minedBlockNumber = await web3.eth.getBlockNumber();

    assert.equal(
      owner,
      accounts[0],
      "Owner wasn't correctly set."
    );
    assert.equal(
      bestSolution,
      0,
      "BestSolution wasn't initialized with 0."
    );
    assert.equal(
      durationInBlocks,
      args.durationInBlocks,
      "DurationInBlocks wasn't correctly set."
    );
    assert.equal(
      competitionEnd,
      minedBlockNumber + durationInBlocks,
      "DurationInBlocks wasn't correctly set."
    );
    assert.equal(
      addressOfWinner,
      '0x0000000000000000000000000000000000000000',
      "AddressOfWinner wasn't correctly initialized with ZERO_ADDRESS."
    );
    assert.equal(
      claimPeriodeLength,
      args.durationInBlocks,
      "ClaimPeriodeLength wasn't correctly set."
    );
  });

  it("...should set correct values when submitting new valid solution.", async () => {
    const instance = await LOPB.deployed({ ...args });
    const x1 = 1;
    const x2 = 1;
    await instance.submitSolution.call(x1, x2);

    const instance_x1 = await instance.x1();
    const instance_x2 = await instance.x2();
    const instance_bestSolution = await instance.bestSolution();
    const instance_addressOfWinner = await instance.addressOfWinner();

    assert.equal(
      instance_x1,
      x1,
      "x1 value wasn't correctly set."
    );
    assert.equal(
      instance_x2,
      x2,
      "x2 value wasn't correctly set."
    );
    // NOTE: update this if the problem in the contract is changed
    assert.equal(
      instance_bestSolution,
      (4 * x1) + (6 * x2),
      "BestSolution value wasn't correctly set."
    );
    assert.equal(
      instance_addressOfWinner,
      accounts[0],
      "AddressOfWinner wasn't correctly set."
    );
  });

  it("...should increase bounty.", async () => {
    const instance = await LOPB.deployed({ ...args });
    const contractBalance_BeforeTopUp = web3.eth.getBalance(instance);
    const transactionValue_inEth = 1;
    const transactionValue_inWei = web3.utils.toWei(transactionValue_inEth);
    // top up bounty
    await instance.topUpBounty.call({}, { from: account[0], value: transactionValue_inWei });

    const contractBalance_AfterTopUp = web3.eth.getBalance(instance);
    assert.equal(
      contractBalance_BeforeTopUp,
      contractBalance_AfterTopUp - transactionValue_inWei,
      "Bounty was not correctly increased."
    );
  });

  // TODO: this is not complete
  // TODO: Hmmm, need to create 'claimPeriodeLength = 6172' blocks
  //       so that block.number > (self.competitionEnd + self.claimPeriodeLength)
  //       not sure how to test this...
  it("...should claim bounty.", async () => {
    const instance = await LOPB.deployed({ ...args });

    const contractBalance_Before = web3.eth.getBalance(instance);
    const competitionEnd_Before = await instance.competitionEnd();
    const x1 = 1;
    const x2 = 1;
    const transactionValue_inEth = 1;
    const transactionValue_inWei = web3.utils.toWei(transactionValue_inEth);
    // top up bounty
    await instance.topUpBounty.call({}, { from: account[0], value: transactionValue_inWei });
    const contractBalance_After = web3.eth.getBalance(instance);
    await instance.claimBounty();

    const competitionEnd_After = await instance.competitionEnd();

  });

  // TODO:
  it("...should extend competition.", async () => {
    const instance = await LOPB.deployed({ durationInBlocks: 1 });
    const durationInBlocks = await instance.durationInBlocks();
    const competitionEnd_Before = await instance.competitionEnd();

    // TODO: Hmmm, need to create 'claimPeriodeLength = 6172' blocks
    //      so that block.number > (self.competitionEnd + self.claimPeriodeLength)
    //      not sure how to test this...

    /*
    // create dummy block

    const result = await web3.eth.sendTransaction({
      from: account[0],
      to: '0x0000000000000000000000000000000000000000',
      value: 1, // in wei
    });
    */
  });
});


<|start_filename|>erc721/migrations/2_deploy_contracts.js<|end_filename|>
var ERC721 = artifacts.require("erc721");

module.exports = function(deployer) {
  deployer.deploy(ERC721);
};


<|start_filename|>linear_optimization_problem_bounty/migrations/2_deploy_contracts.js<|end_filename|>
var LOPB = artifacts.require("linear_optimization_problem_bounty");

module.exports = function(deployer) {
  const durationInBlocks = 100;
  deployer.deploy(durationInBlocks);
};


<|start_filename|>erc20/migrations/2_deploy_contracts.js<|end_filename|>
var ERC20 = artifacts.require("erc20");

module.exports = function(deployer) {
  const name = "MyToken";
  const symbol = "MT";
  const decimals = 18;
  const totalSupply = 100000000;
  deployer.deploy(ERC20, name, symbol, decimals, totalSupply);
};


<|start_filename|>erc1155/migrations/2_deploy_contracts.js<|end_filename|>
var ERC1155 = artifacts.require("erc1155");

module.exports = function(deployer) {
  //deployer.deploy(ERC1155, name, symbol, decimals, totalSupply);
};


<|start_filename|>linear_optimization_problem_bounty/truffle.js<|end_filename|>
module.exports = {
  networks: {
    ganache: {
      host: '127.0.0.1',
      port: 7545,
      network_id: '*', // match any network id
      from: '0x954e72fdc51Cf919203067406fB337Ed4bDC8CdA', // account address from which to deploy
      gas: 4000000,
    }
  }
}


<|start_filename|>wallet/test/wallet.js<|end_filename|>
const erc20  = artifacts.require('erc20');
const erc721 = artifacts.require('erc721');
const erc777 = artifacts.require('erc777');

const walletAbstraction = artifacts.require('wallet');

let wallet, walletOwner;

contract('wallet', accounts => {
  beforeEach(async () => {
    wallet = await walletAbstraction.new({ from: accounts[0] });
    walletOwner = accounts[0];
  });

  it('...should accept eth deposit.', async () => {
    const sender = accounts[0];

    const wallet_starting_balance = await web3.eth.getBalance(wallet.address);

    const amount = web3.utils.toWei('1', 'ether');

    await web3.eth.sendTransaction({
      from: sender,
      to: wallet.address,
      value: amount
    });

    const wallet_ending_balance = await web3.eth.getBalance(wallet.address);

    assert.equal(
      wallet_starting_balance,
      wallet_ending_balance - amount,
      'ETH was not correctly deposited.'
    );
  });

  it('...should send eth.', async () => {
    const sender = accounts[0];
    const receiver = accounts[1];

    const amount = web3.utils.toWei('1', 'ether');

    await web3.eth.sendTransaction({
      from: sender,
      to: wallet.address,
      value: amount
    });

    const wallet_starting_balance = await web3.eth.getBalance(wallet.address);
    const receiver_starting_balance = await web3.eth.getBalance(receiver);

    await wallet.sendETH(receiver, amount, { from: walletOwner, gas: 40000 });

    const wallet_ending_balance = await web3.eth.getBalance(wallet.address);
    const receiver_ending_balance = await web3.eth.getBalance(receiver);

    assert.equal(
      wallet_starting_balance - amount,
      wallet_ending_balance,
      'ETH was not correctly sent.'
    );
    assert.equal(
      receiver_starting_balance,
      receiver_ending_balance - amount,
      'ETH was not correctly sent.'
    );
  });

  it('...should accept erc20 tokens deposit.', async () => {
    const sender = accounts[0];

    const erc20Token = await erc20.deployed();

    const wallet_starting_balance = await erc20Token.balanceOf.call(wallet.address);

    const amount = 100;

    await erc20Token.transfer(wallet.address, amount, { from: sender });

    const wallet_ending_balance = await erc20Token.balanceOf.call(wallet.address);

    assert.equal(
      wallet_starting_balance,
      wallet_ending_balance - amount,
      'ERC20 tokens were not correctly deposited.'
    );
  });

  it('...should send erc20 tokens.', async () => {
    const receiver = accounts[1];

    const amount = 100;

    const erc20Token = await erc20.deployed();
    await erc20Token.transfer(wallet.address, amount, { from: accounts[0] });

    let receiver_starting_balance = await erc20Token.balanceOf.call(receiver);

    await wallet.sendERC20(erc20Token.address, receiver, amount, { from: walletOwner, gas: 4000000 });

    balance = await erc20Token.balanceOf.call(receiver);
    const receiver_ending_balance = balance.toString();

    assert.equal(
      receiver_starting_balance,
      receiver_ending_balance - amount,
      'ERC20 tokens were not correctly credited.'
    );
  });

  it('...should accept erc721 token deposit.', async () => {
    const sender = accounts[0];

    const erc721Token = await erc721.deployed();

    const mintReturnData = await erc721Token.mint();
    const tokenId = mintReturnData.logs[0].args['1'].toString();

    let balance = await erc721Token.balanceOf.call(wallet.address);
    const wallet_starting_balance = balance.toString();

    await erc721Token.transferFrom(sender, wallet.address, tokenId, { from: sender });

    balance = await erc721Token.balanceOf.call(wallet.address);
    const wallet_ending_balance = balance.toString();

    const ownerOfNFT = await erc721Token.ownerOf.call(tokenId);

    assert.equal(
      wallet_starting_balance,
      wallet_ending_balance - 1,
      'ERC721 token was not correctly deposited'
    );
    assert.equal(
      wallet.address,
      ownerOfNFT,
      'ERC721 token was not correctly deposited.'
    );
  });

  it('...should accept erc777 tokens deposit.', async () => {
    const amount = 80;

    const erc777Token = await erc777.deployed();

    const wallet_starting_balance = await erc777Token.balanceOf.call(wallet.address);

    await erc777Token.mint(wallet.address, amount);

    const wallet_ending_balance = await erc777Token.balanceOf.call(wallet.address);

    assert.equal(
      wallet_starting_balance,
      wallet_ending_balance - amount,
      'ERC777 token was not correctly deposited.'
    );
  });

  it('...should send erc777 tokens.', async () => {
    const receiver = accounts[1];

    const amount = 120;

    const erc777Token = await erc777.deployed();
    await erc777Token.mint(wallet.address, amount);

    const wallet_starting_balance = await erc777Token.balanceOf.call(wallet.address);

    await wallet.sendERC777(erc777Token.address, receiver, amount, { from: walletOwner, gas: 3000000 });

    const wallet_ending_balance = await erc777Token.balanceOf.call(wallet.address);

    assert.equal(
      wallet_starting_balance - amount,
      wallet_ending_balance,
      'ERC777 token was not correctly sent.'
    );
  });

});


<|start_filename|>vyperStorage/test/vyperStorage.js<|end_filename|>
const vyperStorage = artifacts.require('vyperStorage');

contract('vyperStorage', () => {
  it('...should initialize storage with 0.', async () => {
    const storage = await vyperStorage.deployed();

    const storedData = await storage.stored_data();

    assert.equal(
      storedData,
      0,
      'The value 89 was not stored.'
    );
  });

  it('...should store the value 89.', async () => {
    const storage = await vyperStorage.deployed();

    await storage.set(89);

    const storedData = await storage.stored_data();

    assert.equal(
      storedData,
      89,
      'The value 89 was not stored.'
    );
  });
});


<|start_filename|>erc777/test/erc777.js<|end_filename|>
const              erc777 = artifacts.require('erc777');
const erc777TokenReceiver = artifacts.require('erc777TokenReceiver');
const   erc777TokenSender = artifacts.require('erc777TokenSender');
const     erc1820Registry = artifacts.require('ERC1820Registry');

const truffleFromAddress = '0x954e72fdc51Cf919203067406fB337Ed4bDC8CdA';

const args = {
  name: 'My777Token',
  symbol: 'MT777',
  totalSupply: 100000000,
  granularity: 10,
  defaultOperators: [
    truffleFromAddress,
    '0x0000000000000000000000000000000000000001',
    '0x0000000000000000000000000000000000000002',
    '0x0000000000000000000000000000000000000003',
  ],
}

let defaultOperator,
    holder,
    operator,
    receiver,

    erc777Token,

    zeroAddress;

contract('ERC777', async accounts => {
  beforeEach(async () => {
    defaultOperator = accounts[0];
             holder = accounts[1];
           operator = accounts[2];
           receiver = accounts[3];
        zeroAddress = '0x0000000000000000000000000000000000000000'

    erc777Token = await erc777.new(
      args.name,
      args.symbol,
      args.totalSupply,
      args.granularity,
      args.defaultOperators,
      { from: defaultOperator }
    );
  });

  it('...should set correct vanity information', async () => {
    const name = await erc777Token.name.call();
    assert.strictEqual(name, args.name);

    const symbol = await erc777Token.symbol.call();
    assert.strictEqual(symbol, args.symbol);

    const totalSupply = await erc777Token.totalSupply.call();
    assert.strictEqual(totalSupply.toNumber(), args.totalSupply);

    const granularity = await erc777Token.granularity.call();
    assert.strictEqual(granularity.toNumber(), args.granularity);

    const defaultOperators = await erc777Token.defaultOperators.call();
    assert.strictEqual(defaultOperators.toString(), args.defaultOperators.toString());
  });

  it('...should register ERC1820 `ERC777Token` interface.', async () => {
    const erc1820JsonInterface = erc1820Registry.abi;
    const erc1820Address = '0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24';
    const erc1820Instance = new web3.eth.Contract(erc1820JsonInterface, erc1820Address);

    const interfaceHash = web3.utils.keccak256('ERC777Token');
    const interfaceHash_implementer = await erc1820Instance.methods.getInterfaceImplementer(erc777Token.address, interfaceHash).call();

    const interfaceHash_correct = '0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054';

    assert.strictEqual(interfaceHash, interfaceHash_correct);
    assert.strictEqual(interfaceHash_implementer, erc777Token.address);
  });

  it('...default operator should mint tokens.', async () => {
    const operator_balance_before = await erc777Token.balanceOf.call(defaultOperator);

    const amount = 100;
    await erc777Token.mint(defaultOperator, amount);

    const operator_balance_after = await erc777Token.balanceOf.call(defaultOperator);

    assert.equal(
      operator_balance_before,
      operator_balance_after - amount,
      'Receiver balance was not correctly updated.'
    );
  });

  it('...non default operator should not mint tokens.', async () => {
    const amount = 100;

    try {
      await erc777Token.mint(receiver, amount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'Mint from non default operator did not revert.'
    );
  });

  it('...holder should send tokens.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const   holder_balance_before = await erc777Token.balanceOf.call(holder);
    const receiver_balance_before = await erc777Token.balanceOf.call(receiver);

    await erc777Token.send(receiver, amount, { from: holder });

    const   holder_balance_after = await erc777Token.balanceOf.call(holder);
    const receiver_balance_after = await erc777Token.balanceOf.call(receiver);

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      receiver_balance_before.toString(),
      receiver_balance_after - amount,
      'Receiver balance was not correctly updated.'
    );
  });

  it('...holder should not send tokens to ZERO_ADDRESS.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.send(zeroAddress, amount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'Send to ZERO_ADDRESS did not revert.'
    )
  });

  it('...holder should authorizeOperator.', async () => {
    const newOperator = accounts[2];

    const operator_status_before = await erc777Token.isOperatorFor.call(newOperator, holder);

    await erc777Token.authorizeOperator(newOperator, { from: holder });

    const operator_status_after = await erc777Token.isOperatorFor.call(newOperator, holder);

    assert.isNotOk(
      operator_status_before,
      'Operators for holder are not correctly filtered.'
    );
    assert.isOk(
      operator_status_after,
      'Holder did not correctly authorize operator.'
    );
  });

  it('...holder should revokeOperator.', async () => {
    await erc777Token.authorizeOperator(operator, { from: holder });
    const operator_status_before = await erc777Token.isOperatorFor.call(operator, holder);

    await erc777Token.revokeOperator(operator, { from: holder });

    const operator_status_after = await erc777Token.isOperatorFor.call(operator, holder);

    assert.isOk(
      operator_status_before,
      'Operators for holder were not correctly filtered.'
    );
    assert.isNotOk(
      operator_status_after,
      'Operator rights were not correctly revoked.'
    );
  });

  it('...holder should do operatorSend.', async () => {
    // "holder should be operator for self"
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const   holder_balance_before = await erc777Token.balanceOf.call(holder);
    const receiver_balance_before = await erc777Token.balanceOf.call(receiver);

    await erc777Token.operatorSend(holder, receiver, amount, { from: holder });

    const   holder_balance_after = await erc777Token.balanceOf.call(holder);
    const receiver_balance_after = await erc777Token.balanceOf.call(receiver);

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      receiver_balance_before.toString(),
      receiver_balance_after - amount,
      'Receiver balance was not correctly updated.'
    );
  });

  it('...defaultOperator should do operatorSend.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const   holder_balance_before = await erc777Token.balanceOf.call(holder);
    const receiver_balance_before = await erc777Token.balanceOf.call(receiver);

    await erc777Token.operatorSend(holder, receiver, amount, { from: defaultOperator });

    const   holder_balance_after = await erc777Token.balanceOf.call(holder);
    const receiver_balance_after = await erc777Token.balanceOf.call(receiver);

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      receiver_balance_before.toString(),
      receiver_balance_after - amount,
      'Receiver balance was not correctly updated.'
    );
  });

  it('...approved operator should do operatorSend.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder });

    const   holder_balance_before = await erc777Token.balanceOf.call(holder);
    const receiver_balance_before = await erc777Token.balanceOf.call(receiver);

    await erc777Token.operatorSend(holder, receiver, amount, { from: operator });

    const   holder_balance_after = await erc777Token.balanceOf.call(holder);
    const receiver_balance_after = await erc777Token.balanceOf.call(receiver);

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      receiver_balance_before.toString(),
      receiver_balance_after - amount,
      'Receiver balance was not correctly updated.'
    );
  });

  it('...holder should not operatorSend tokens to ZERO_ADDRESS.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorSend(holder, zeroAddress, amount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by holder) to ZERO_ADDRESS did not revert.'
    )
  });

  it('...defaultOperator should not operatorSend tokens to ZERO_ADDRESS.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorSend(holder, zeroAddress, amount, { from: defaultOperator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by defaultOperator) to ZERO_ADDRESS did not revert.'
    )
  });

  it('...approved operator should not operatorSend tokens to ZERO_ADDRESS.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder });

    try {
      await erc777Token.operatorSend(holder, zeroAddress, amount, { from: operator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by approved operator) to ZERO_ADDRESS did not revert.'
    )
  });

  it('...non operator should not do operatorSend.', async () => {
    const receiver2 = accounts[4];

    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorSend(holder, receiver2, amount, { from: receiver });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend from non operator did not revert.'
    );
  });

  it('...holder should do burn.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const holder_balance_before = await erc777Token.balanceOf.call(holder);
    const totalSupply_before = await erc777Token.totalSupply.call();

    await erc777Token.burn(amount, { from: holder });

    const holder_balance_after = await erc777Token.balanceOf.call(holder);
    const totalSupply_after = await erc777Token.totalSupply.call();

    assert.equal(
      totalSupply_before - amount,
      totalSupply_after.toString(),
      'TotalSupply was not correcty updated.'
    );
    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
  });

  it('...defaultOperator should do operatorBurn.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const holder_balance_before = await erc777Token.balanceOf.call(holder);
    const totalSupply_before = await erc777Token.totalSupply.call();

    await erc777Token.operatorBurn(holder, amount, { from: defaultOperator });

    const holder_balance_after = await erc777Token.balanceOf.call(holder);
    const totalSupply_after = await erc777Token.totalSupply.call();

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      totalSupply_before - amount,
      totalSupply_after.toString(),
      'TotalSupply was not correcty updated.'
    );
  });

  it('...approved operator should do operatorBurn.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder })

    const holder_balance_before = await erc777Token.balanceOf.call(holder);
    const totalSupply_before = await erc777Token.totalSupply.call();

    await erc777Token.operatorBurn(holder, amount, { from: operator });

    const holder_balance_after = await erc777Token.balanceOf.call(holder);
    const totalSupply_after = await erc777Token.totalSupply.call();

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      totalSupply_before - amount,
      totalSupply_after.toString(),
      'TotalSupply was not correcty updated.'
    );
  });

  it('...holder should do operatorBurn.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder })

    const holder_balance_before = await erc777Token.balanceOf.call(holder);
    const totalSupply_before = await erc777Token.totalSupply.call();

    await erc777Token.operatorBurn(holder, amount, { from: holder });

    const holder_balance_after = await erc777Token.balanceOf.call(holder);
    const totalSupply_after = await erc777Token.totalSupply.call();

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      totalSupply_before - amount,
      totalSupply_after.toString(),
      'TotalSupply was not correcty updated.'
    );
  });

  it('...non operator should not do operatorBurn.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorBurn(holder, amount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorBurn from non operator did not revert.'
    )
  });

  it('...should not accept ETH.', async () => {
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const accBalance = await web3.eth.getBalance(holder);
    const oneEth = await web3.utils.toWei('1', 'ether');

    try {
      await web3.eth.sendTransaction({ from: holder, to: erc777Token.address, value: oneEth });
    } catch (e) {
      revert = e;
    }

    assert.isOk(
      accBalance >= oneEth,
      'Account was not funded well enough.'
    );
    assert.instanceOf(
      revert,
      Error,
      'Ether send to contract did not revert.'
    );
  });

  it('...defaultOperator should not mint with wrong granularity.', async () => {
    const wrongAmount = 101;

    try {
      await erc777Token.mint(holder, wrongAmount, { from: defaultOperator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'Mint with wrong granularity did not revert.'
    );
  });

  it('...holder should not send with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.send(receiver, wrongAmount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'Send with wrong granularity did not revert.'
    );
  });

  it('...holder should not operatorSend with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorSend(holder, receiver, wrongAmount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by holder) with wrong granularity did not revert.'
    );
  });

  it('...approved operator should not operatorSend with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder })

    try {
      await erc777Token.operatorSend(holder, receiver, wrongAmount, { from: operator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by approved operator) with wrong granularity did not revert.'
    );
  });

  it('...defaultOperator should not operatorSend with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorSend(holder, receiver, wrongAmount, { from: defaultOperator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by defaultOperator) with wrong granularity did not revert.'
    );
  });

  it('...holder should not burn with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.burn(wrongAmount, { from: holder });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorSend (by holder) with wrong granularity did not revert.'
    );
  });

  it('...approved operator should not operatorBurn with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder });

    try {
      await erc777Token.operatorBurn(holder, wrongAmount, { from: operator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorBurn (by approved operator) with wrong granularity did not revert.'
    );
  });

  it('...defaultOperator should not burn with wrong granularity.', async () => {
    const amount = 200;
    const wrongAmount = 101;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    try {
      await erc777Token.operatorBurn(holder, wrongAmount, { from: defaultOperator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'OperatorBurn (by approved operator) with wrong granularity did not revert.'
    );
  });

  /*
    TODO: Test hooks
          - should call hooks on:
              - holder send
              - operator send
              - mint
              - burn
              - operatorBurn
  */

  /*
  it('...should call `tokensReceived` hook.', async () => {
    const erc777Receiver = await erc777TokenReceiver.new({ from: receiver });

    const amount = 200;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const   holder_balance_before = await erc777Token.balanceOf.call(holder);
    const receiver_balance_before = await erc777Token.balanceOf.call(erc777Receiver.address);

    const result1 = await erc777Token.send(erc777Receiver.address, amount, { from: holder });
    console.log(result1)
    const result2 = await erc777Receiver.tokensReceived(holder, holder, erc777Receiver.address, amount, null, null)
    console.log(result2)

    const   holder_balance_after = await erc777Token.balanceOf.call(holder);
    const receiver_balance_after = await erc777Token.balanceOf.call(erc777Receiver.address);

    assert.equal(
      holder_balance_before - amount,
      holder_balance_after.toString(),
      'Holder balance was not correctly updated.'
    );
    assert.equal(
      receiver_balance_before.toString(),
      receiver_balance_after - amount,
      'Receiver balance was not correctly updated.'
    );
  });
  */
  /* TODO
  it('...should call `tokensToSend` hook.', async () => {

  });
  */

  it('...should not deploy with granularity of 0.', async () => {
    try {
      await erc777.new(
        args.name,
        args.symbol,
        args.totalSupply,
        0,
        args.defaultOperators,
        { from: defaultOperator }
      );
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'Deploy with granularity of 0 did not revert.'
    );
  });

  // Test event logging
  it('...should log Minted on mint().', async () => {
    /*
    _operator: indexed(address), # Address which triggered the mint.
    _to: indexed(address),       # Recipient of the tokens.
    _amount: uint256,            # Number of tokens minted.
    _data: bytes[256],           # Information provided for the recipient.
    _operatorData: bytes[256]    # Information provided by the operator.
    */
    const amount = 100;
    const res = await erc777Token.mint(holder, amount, { from: defaultOperator });
    const log = res.logs.find(element => element.event.match('Mint'));

    assert.strictEqual(log.args._operator, defaultOperator);
    assert.strictEqual(log.args._to, holder);
    assert.equal(log.args._amount.toString(), amount);
    assert.strictEqual(log.args._data, null);
    assert.strictEqual(log.args._operatorData, null);
  })

  it('...should log Sent on send().', async () => {
    /*
    _operator: indexed(address), # Address which triggered the send.
    _from: indexed(address),     # Token holder.
    _to: indexed(address),       # Token recipient.
    _amount: uint256,            # Number of tokens to send.
    _data: bytes[256],           # Information provided by the token holder.
    _operatorData: bytes[256]    # Information provided by the operator.
     */
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const res = await erc777Token.send(receiver, amount, { from: holder });
    const log = res.logs.find(element => element.event.match('Sent'));

    assert.strictEqual(log.args._operator, holder);
    assert.strictEqual(log.args._from, holder);
    assert.strictEqual(log.args._to, receiver);
    assert.equal(log.args._amount.toString(), amount);
    assert.strictEqual(log.args._data, null);
    assert.strictEqual(log.args._operatorData, null);
  })

  it('...should log Sent on operatorSend().', async () => {
    /*
    _operator: indexed(address), # Address which triggered the send.
    _from: indexed(address),     # Token holder.
    _to: indexed(address),       # Token recipient.
    _amount: uint256,            # Number of tokens to send.
    _data: bytes[256],           # Information provided by the token holder.
    _operatorData: bytes[256]    # Information provided by the operator.
     */
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const res = await erc777Token.operatorSend(holder, receiver, amount, { from: holder });
    const log = res.logs.find(element => element.event.match('Sent'));

    assert.strictEqual(log.args._operator, holder);
    assert.strictEqual(log.args._from, holder);
    assert.strictEqual(log.args._to, receiver);
    assert.equal(log.args._amount.toString(), amount);
    assert.strictEqual(log.args._data, null);
    assert.strictEqual(log.args._operatorData, null);
  })

  it('...should log Burned on burn().', async () => {
    /*
    _operator: indexed(address), # Address which triggered the burn.
    _from: indexed(address),     # Token holder whose tokens are burned.
    _amount: uint256,            # Token holder whose tokens are burned.
    _data: bytes[256],           # Information provided by the token holder.
    _operatorData: bytes[256]    # Information provided by the operator.
    */
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });

    const res = await erc777Token.burn(amount, { from: holder });
    const log = res.logs.find(element => element.event.match('Burned'));

    assert.strictEqual(log.args._operator, holder);
    assert.strictEqual(log.args._from, holder);
    assert.equal(log.args._amount.toString(), amount);
    assert.strictEqual(log.args._data, null);
    assert.strictEqual(log.args._operatorData, null);
  })

  it('...should log Burned on operatorBurn().', async () => {
    /*
    _operator: indexed(address), # Address which triggered the burn.
    _from: indexed(address),     # Token holder whose tokens are burned.
    _amount: uint256,            # Token holder whose tokens are burned.
    _data: bytes[256],           # Information provided by the token holder.
    _operatorData: bytes[256]    # Information provided by the operator.
    */
    const amount = 100;
    await erc777Token.mint(holder, amount, { from: defaultOperator });
    await erc777Token.authorizeOperator(operator, { from: holder })

    const res = await erc777Token.operatorBurn(holder, amount, { from: operator });
    const log = res.logs.find(element => element.event.match('Burned'));

    assert.strictEqual(log.args._operator, operator);
    assert.strictEqual(log.args._from, holder);
    assert.equal(log.args._amount.toString(), amount);
    assert.strictEqual(log.args._data, null);
    assert.strictEqual(log.args._operatorData, null);
  })

  it('...should log AuthorizedOperator on authorizeOperator().', async () => {
    /*
    _operator: indexed(address), # Address which became an operator of tokenHolder.
    _holder: indexed(address)    # Address of a token holder which authorized the operator address as an operator.
    */
    const newOperator = accounts[2];

    const res = await erc777Token.authorizeOperator(newOperator, { from: holder });
    const log = res.logs.find(element => element.event.match('AuthorizedOperator'));

    assert.strictEqual(log.args._operator, newOperator);
    assert.strictEqual(log.args._holder, holder);
  })

  it('...should log RevokedOperator on revokeOperator().', async () => {
    /*
    _operator: indexed(address), # Address which was revoked as an operator of tokenHolder.
    _holder: indexed(address)    # Address of a token holder which revoked the operator address as an operator.
    */
    await erc777Token.authorizeOperator(operator, { from: holder });

    const res = await erc777Token.revokeOperator(operator, { from: holder });
    const log = res.logs.find(element => element.event.match('RevokedOperator'));

    assert.strictEqual(log.args._operator, operator);
    assert.strictEqual(log.args._holder, holder);
  })

  // TODO: Test use of data and opeator data in all variations (send, transfer, events, etc.)
  // TODO: Test send/operatorSend/mint/burn with negative values
  // TODO: Test send/operatorSend/mint/burn with zero values
  // TODO: Test send/operatorSend/mint/burn with using default parameters
});


<|start_filename|>wallet/migrations/1_initial_migration.js<|end_filename|>
const checkForERC182Registry = require('./helpers/checkForERC182Registry.js');

const Migrations = artifacts.require('./Migrations.sol');

module.exports = async function(deployer) {
  await checkForERC182Registry(web3, deployer);

  deployer.deploy(Migrations);
};


<|start_filename|>erc1155/test/erc1155.js<|end_filename|>
const ERC1155Abstraction = artifacts.require('erc1155');

contract('ERC1155', (accounts) => {
  /*
  beforeEach(async () => {
    ERC1155 = await ERC1155Abstraction.new(

      { from: accounts[0] }
    );
  });
  */
});


<|start_filename|>wallet/migrations/2_deploy_contracts.js<|end_filename|>
const erc20  = artifacts.require('erc20');
const erc721 = artifacts.require('erc721');
const erc777 = artifacts.require('erc777');
const wallet = artifacts.require('wallet');

const truffleFromAddress = '0x954e72fdc51Cf919203067406fB337Ed4bDC8CdA';

const args = {
  erc20: {
    name: 'My20Token',
    symbol: 'MT20',
    decimals: 18,
    totalSupply: 100000000,
  },
  erc777: {
    name: 'My777Token',
    symbol: 'MT777',
    totalSupply: 100000000,
    granularity: 1,
    defaultOperators: [
      truffleFromAddress,
      '0x0000000000000000000000000000000000000001',
      '0x0000000000000000000000000000000000000002',
      '0x0000000000000000000000000000000000000003',
    ],
  }
}

module.exports = function(deployer) {
  if (deployer.network == 'ganache') {
    // deploy contracts necessary for testing
    deployer.deploy(
      erc20,
      args.erc20.name,
      args.erc20.symbol,
      args.erc20.decimals,
      args.erc20.totalSupply,
    );

    deployer.deploy(erc721);

    deployer.deploy(
      erc777,
      args.erc777.name,
      args.erc777.symbol,
      args.erc777.totalSupply,
      args.erc777.granularity,
      args.erc777.defaultOperators,
    );
  } // if deployer.network == 'ganache'

  // deploy wallet contract
  deployer.deploy(wallet);
};


<|start_filename|>erc721/test/erc721.js<|end_filename|>
const erc721 = artifacts.require("erc721");

let owner,
    receiver,
    operator,
    erc721Token;

const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const ERC165_INTERFACE_ID = '0x0000000000000000000000000000000000000000000000000000000001ffc9a7';
const ERC721_INTERFACE_ID = '0x0000000000000000000000000000000000000000000000000000000080ac58cd';

contract("ERC721", async accounts => {
  beforeEach(async () => {
    owner = accounts[0];
    receiver = accounts[1];
    operator = accounts[2];
    erc721Token = await erc721.new({ from: owner });
  });

  it("...should register ERC165 interface.", async () => {
    const has_erc165_interface = await erc721Token.supportsInterface.call(ERC165_INTERFACE_ID);
    assert.ok(has_erc165_interface, "The ERC165 interface was not correctly registered.");
  });

  it("...should register ERC721 interface.", async () => {
    const has_erc721_interface = await erc721Token.supportsInterface.call(ERC721_INTERFACE_ID);
    assert.ok(has_erc721_interface, "The ERC721 interface was not correctly registered.");
  });

  it("...should mint token to owner.", async () => {
    let balance = await erc721Token.balanceOf.call(owner);
    const minter_starting_balance = balance.toString();

    // TODO: weird -> we are getting the token id from the mint event parameters
    //       how to get the return value of mint()??
    let returnData = await erc721Token.mint({ from: owner });
    const tokenId_1 = returnData.logs[0].args['1'].toString();
    returnData = await erc721Token.mint({ from: owner });
    const tokenId_2 = returnData.logs[0].args['1'].toString();

    const ownerOfToken_1 = await erc721Token.ownerOf.call(tokenId_1);
    const ownerOfToken_2 = await erc721Token.ownerOf.call(tokenId_2);

    balance = await erc721Token.balanceOf.call(owner);
    const minter_ending_balance = balance.toString();

    assert.equal(
      tokenId_1,
      0,
      "Token ID wasn't correctly set."
    );
    assert.equal(
      tokenId_2,
      1,
      "Token ID wasn't correctly set."
    );
    assert.equal(
      minter_starting_balance,
      minter_ending_balance - 2,
      "Token wasn't correctly minted to owner."
    );
    assert.equal(
      ownerOfToken_1,
      owner,
      "Owner of first minted token wasn't correctly set."
    );
    assert.equal(
      ownerOfToken_2,
      owner,
      "Owner of second minted token wasn't correctly set."
    );
  });

  // TODO:
  it("...mint should revert if msg.sender is not owner.", async () => {
    try {
      await erc721Token.mint({ from: receiver });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      'Mint by non owner did not revert.'
    )
  });

  it("...should safeTransferFrom.", async () => {
    // TODO: weird -> we are getting the token id from the mint event parameters
    //       how to get the return value of mint()??
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    const ownerBalanceBefore = await erc721Token.balanceOf.call(owner);
    const receiverBalanceBefore = await erc721Token.balanceOf.call(receiver);
    const ownerOfTokenBefore = await erc721Token.ownerOf.call(tokenId);

    await erc721Token.safeTransferFrom(owner, receiver, tokenId);

    const ownerBalanceAfter = await erc721Token.balanceOf.call(owner);
    const receiverBalanceAfter = await erc721Token.balanceOf.call(receiver);
    const ownerOfTokenAfter = await erc721Token.ownerOf.call(tokenId);

    assert.equal(
      ownerBalanceBefore - 1,
      ownerBalanceAfter.toString(),
      "Balance of owner wasn't correctly updated."
    );

    assert.equal(
      receiverBalanceBefore.toString(),
      receiverBalanceAfter - 1,
      "Balance of reveiver wasn't correctly updated."
    );

    assert.equal(
      ownerOfTokenAfter,
      receiver,
      "Owner of token wasn't correctly updated."
    );
  });

  it("...should transferFrom.", async () => {
    // TODO: weird -> we are getting the token id from the mint event parameters
    //       how to get the return value of mint()??
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    const ownerBalanceBefore = await erc721Token.balanceOf.call(owner);
    const receiverBalanceBefore = await erc721Token.balanceOf.call(receiver);
    const ownerOfTokenBefore = await erc721Token.ownerOf.call(tokenId);

    await erc721Token.transferFrom(owner, receiver, tokenId);

    const ownerBalanceAfter = await erc721Token.balanceOf.call(owner);
    const receiverBalanceAfter = await erc721Token.balanceOf.call(receiver);
    const ownerOfTokenAfter = await erc721Token.ownerOf.call(tokenId);

    assert.equal(
      ownerBalanceBefore - 1,
      ownerBalanceAfter.toString(),
      "Balance of owner wasn't correctly updated."
    );

    assert.equal(
      receiverBalanceBefore.toString(),
      receiverBalanceAfter - 1,
      "Balance of reveiver wasn't correctly updated."
    );

    assert.equal(
      ownerOfTokenAfter,
      receiver,
      "Owner of token wasn't correctly updated."
    );
  });

  // TODO:
  it("...safeTransferFrom() to contract without onERC721Received should revert.", async () => {

  });

  it("...safeTransferFrom() to ZERO_ADDRESS should revert.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      const result = await erc721Token.safeTransferFrom(owner, ZERO_ADDRESS, tokenId);
    } catch (e) {
      revert = e;
    }
    assert.instanceOf(
      revert,
      Error,
      "SafeTransferFrom to ZERO_ADDRESS did not revert."
    )
  });

  it("...transferFrom() to ZERO_ADDRESS should revert.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      const result = await erc721Token.transferFrom(owner, ZERO_ADDRESS, tokenId);
    } catch (e) {
      revert = e;
    }
    assert.instanceOf(
      revert,
      Error,
      "TransferFrom to ZERO_ADDRESS did not revert."
    )
  });

  it("...safeTransferFrom() should revert if 'tokenId' is not a valid NFT.", async () => {
    const tokenId = -1

    let revert = false;
    try {
      await erc721Token.safeTransferFrom(owner, receiver, tokenId);
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "SafeTransferFrom of non valid NFT did not revert."
    )
  });

  it("...transferFrom() should revert if 'tokenId' is not a valid NFT.", async () => {
    const tokenId = -1

    let revert = false;
    try {
      await erc721Token.transferFrom(owner, receiver, tokenId);
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "TransferFrom of non valid NFT did not revert."
    )
  });

  it("...safeTransferFrom() should revert if 'from' is not the owner.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      await erc721Token.safeTransferFrom(receiver, owner, tokenId);
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "SafeTransferFrom by non owner did not revert."
    )
  });

  it("...transferFrom() should revert if 'from' is not the owner.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      await erc721Token.transferFrom(receiver, owner, tokenId);
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "SafeTransferFrom by non owner did not revert."
    )
  });

  it("...balanceOf() should revert for queries about the ZERO_ADDRESS.", async () => {
    let revert = false;
    try {
      await erc721Token.balanceOf(ZERO_ADDRESS);
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "BalanceOf query about ZERO_ADDRESS did not revert."
    )
  });

  it("...should approve() if is owner.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      await erc721Token.approve(operator, tokenId, { from: owner });
    } catch (e) {
      revert = e;
    }

    const isApproved = await erc721Token.getApproved.call(tokenId);

    assert.isOk(
      isApproved,
      "Operator was not correctly approved."
    );
    assert.isNotOk(
      revert,
      "Operator was not correctly approved."
    );
  });

  it("...approve() should revert if 'tokenId' is not owned by 'msg.sender'.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      await erc721Token.approve(owner, tokenId, { from: operator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "Approve from non owner did not revert."
    )
  });

  it("...approve() should revert if 'tokenId' is not a valid NFT.", async () => {
    let revert = false;
    try {
      await erc721Token.approve(owner, -1, { from: operator });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "Approve of non valid NFT did not revert."
    )
  });

  it("...should approve if is an authorized operator.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    await erc721Token.approve(operator, tokenId, { from: owner });

    await erc721Token.approve(accounts[3], tokenId, { from: operator });

    const isApproved = await erc721Token.getApproved.call(tokenId);

    assert.equal(
      isApproved,
      accounts[3],
      "Authorized operator did not correctly approve."
    );
  });

  it("...approve should revert if 'msg.sender' is not an authorized operator.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    let revert = false;
    try {
      await erc721Token.approve(owner, tokenId, { from: account[3] });
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "Approve call from non authorized operator did not revert."
    )
  });

  it("...should getApproved.", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    await erc721Token.approve(operator, tokenId, { from: owner });

    const isApproved = await erc721Token.getApproved.call(tokenId);

    assert.equal(
      isApproved,
      operator,
      "Did not correctly getApproved."
    );
  });

  it("...should setApprovalForAll.", async () => {
    await erc721Token.setApprovalForAll(operator, true, { from: owner });

    const isApprovedForAll = await erc721Token.isApprovedForAll.call(owner, operator);

    assert.isOk(
      isApprovedForAll,
      "Did not setApprovalForAll."
    );
  });

  it("...isApprovedForAll should return 'False' if address is not approvedForAll.", async () => {
    const isApprovedForAll = await erc721Token.isApprovedForAll.call(owner, accounts[3]);

    assert.isNotOk(
      isApprovedForAll,
      "Did not return 'False' for address that is not approvedForAll."
    );
  });

  it("...getApproved should revert if 'tokenId' is not a valid NFT.", async () => {
    let revert = false;
    try {
      await erc721Token.getApproved.call(-1);
    } catch (e) {
      revert = e;
    }

    assert.instanceOf(
      revert,
      Error,
      "GetApproved of non valid NFT did not revert."
    )
  });

  // Test event logging
  it("...should log 'Minted' on mint().", async () => {
    const res = await erc721Token.mint({ from: owner });
    const log = res.logs.find(element => element.event.match('Mint'));

    assert.strictEqual(log.args._to, owner);
    assert.strictEqual(log.args._tokenId.toString(), "0");
  })

  it("...should log 'Transfer' on safeTransferFrom().", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    const res = await erc721Token.safeTransferFrom(owner, receiver, tokenId);
    const log = res.logs.find(element => element.event.match('Transfer'));

    assert.strictEqual(log.args._from, owner);
    assert.strictEqual(log.args._to, receiver);
    assert.strictEqual(log.args._tokenId.toString(), tokenId);
  })

  it("...should log 'Transfer' on transferFrom().", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    const res = await erc721Token.transferFrom(owner, receiver, tokenId);
    const log = res.logs.find(element => element.event.match('Transfer'));

    assert.strictEqual(log.args._from, owner);
    assert.strictEqual(log.args._to, receiver);
    assert.strictEqual(log.args._tokenId.toString(), tokenId);
  })

  it("...should log 'Approval' on approve().", async () => {
    const returnData = await erc721Token.mint({ from: owner });
    const tokenId = returnData.logs[0].args['1'].toString();

    const res = await erc721Token.approve(operator, tokenId, { from: owner });
    const log = res.logs.find(element => element.event.match('Approval'));

    assert.strictEqual(log.args._owner, owner);
    assert.strictEqual(log.args._approved, operator);
    assert.strictEqual(log.args._tokenId.toString(), tokenId);
  })

  it("...should log 'ApprovalForAll' on setApprovalForAll().", async () => {
    const res = await erc721Token.setApprovalForAll(operator, true, { from: owner });
    const log = res.logs.find(element => element.event.match('ApprovalForAll'));

    assert.strictEqual(log.args._owner, owner);
    assert.strictEqual(log.args._operator, operator);
    assert.strictEqual(log.args._approved, true);
  })
});
