UNPKG

@0xcert/ethereum-erc20-contracts

Version:

Smart contract implementation of the ERC-20 standard on the Ethereum blockchain.

189 lines 11 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const spec_1 = require("@specron/spec"); const spec = new spec_1.Spec(); spec.beforeEach((ctx) => __awaiter(void 0, void 0, void 0, function* () { const accounts = yield ctx.web3.eth.getAccounts(); ctx.set('owner', accounts[0]); ctx.set('bob', accounts[1]); ctx.set('jane', accounts[2]); ctx.set('sara', accounts[3]); })); spec.beforeEach((ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = yield ctx.deploy({ src: './build/token-mock.json', contract: 'TokenMock', args: ['ERC20', 'ERC', 18, '300000000000000000000000000'], }); ctx.set('token', token); })); spec.beforeEach((ctx) => __awaiter(void 0, void 0, void 0, function* () { const BN = ctx.web3.utils.BN; ctx.set('decimalsMul', new BN('1000000000000000000')); ctx.set('totalSupply', new BN('300000000000000000000000000')); })); spec.test('correctly checks all the supported interfaces', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const tokenInterface = yield token.instance.methods.supportsInterface('0x36372b07').call(); const tokenNameInterface = yield token.instance.methods.supportsInterface('0x06fdde03').call(); const tokenSymbolInterface = yield token.instance.methods.supportsInterface('0x95d89b41').call(); const tokenDecimalsInterface = yield token.instance.methods.supportsInterface('0x313ce567').call(); const tokenNoneExistingInterface = yield token.instance.methods.supportsInterface('0x19be5360').call(); ctx.is(tokenInterface, true); ctx.is(tokenNameInterface, true); ctx.is(tokenSymbolInterface, true); ctx.is(tokenDecimalsInterface, true); ctx.is(tokenNoneExistingInterface, false); })); spec.test('has correct totalSupply after construction', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const actualSupply = yield token.instance.methods.totalSupply().call(); const tokenTotalSupply = ctx.get('totalSupply'); ctx.is(actualSupply.toString(), tokenTotalSupply.toString()); })); spec.test('has correct token name after construction', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const actualTokenName = yield token.instance.methods.name().call(); ctx.is(actualTokenName, 'ERC20'); })); spec.test('has correct token symbol after construction', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const actualTokenSymbol = yield token.instance.methods.symbol().call(); ctx.is(actualTokenSymbol, 'ERC'); })); spec.test('has correct token decimals after construction', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const actualTokenDecimals = yield token.instance.methods.decimals().call(); ctx.is(actualTokenDecimals, '18'); })); spec.test('has correct owner token balance after construction', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const actualOwnerBalance = yield token.instance.methods.balanceOf(owner).call(); const ownerBalance = ctx.get('totalSupply'); ctx.is(actualOwnerBalance.toString(), ownerBalance.toString()); })); spec.test('recipient and sender have correct balances after transfer', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); const ownerBalance = ctx.get('totalSupply'); yield token.instance.methods.transfer(bob, tokenAmount.toString()).send({ from: owner }); const actualOwnerBalance = yield token.instance.methods.balanceOf(owner).call(); const actualBobBalance = yield token.instance.methods.balanceOf(bob).call(); ctx.is(actualOwnerBalance.toString(), ownerBalance.sub(tokenAmount).toString()); ctx.is(actualBobBalance.toString(), tokenAmount.toString()); })); spec.test('emits Transfer event on transfer', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); const logs = yield token.instance.methods.transfer(bob, tokenAmount.toString()).send({ from: owner }); ctx.not(logs.events.Transfer, undefined); })); spec.test('throws when trying to transfer more than available balance', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const tokenTotalSupply = ctx.get('totalSupply'); const moreThanBalance = tokenTotalSupply.add(new ctx.web3.utils.BN('1')); yield ctx.reverts(() => token.instance.methods.transfer(bob, moreThanBalance.toString()).send({ from: owner }), '001001'); })); spec.test('returns the correct allowance amount after approval', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); yield token.instance.methods.approve(bob, tokenAmount.toString()).send({ from: owner }); const actualAllowance = yield token.instance.methods.allowance(owner, bob).call(); ctx.is(actualAllowance.toString(), tokenAmount.toString()); })); spec.test('emits Approval event after approval', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); const logs = yield token.instance.methods.approve(bob, tokenAmount.toString()).send({ from: owner }); ctx.not(logs.events.Approval, undefined); })); spec.test('successfully resets allowance', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); const newTokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('50')); yield token.instance.methods.approve(bob, tokenAmount.toString()).send({ from: owner }); yield token.instance.methods.approve(bob, 0).send({ from: owner }); yield token.instance.methods.approve(bob, newTokenAmount.toString()).send({ from: owner }); const actualAllowance = yield token.instance.methods.allowance(owner, bob).call(); ctx.is(actualAllowance.toString(), newTokenAmount.toString()); })); spec.test('returns correct balances after transferring from another account', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const sara = ctx.get('sara'); const decimalsMul = ctx.get('decimalsMul'); const ownerSupply = ctx.get('totalSupply'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); yield token.instance.methods.approve(bob, tokenAmount.toString()).send({ from: owner }); yield token.instance.methods.transferFrom(owner, sara, tokenAmount.toString()).send({ from: bob }); const balanceOwner = yield token.instance.methods.balanceOf(owner).call(); const balanceSara = yield token.instance.methods.balanceOf(sara).call(); const balanceBob = yield token.instance.methods.balanceOf(bob).call(); ctx.is(balanceOwner.toString(), ownerSupply.sub(tokenAmount).toString()); ctx.is(balanceSara.toString(), tokenAmount.toString()); ctx.is(balanceBob.toString(), '0'); })); spec.test('emits Transfer event on transferFrom', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const sara = ctx.get('sara'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); yield token.instance.methods.approve(bob, tokenAmount.toString()).send({ from: owner }); const logs = yield token.instance.methods.transferFrom(owner, sara, tokenAmount.toString()).send({ from: bob }); ctx.not(logs.events.Transfer, undefined); })); spec.test('throws when trying to transferFrom more than allowed amount', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const sara = ctx.get('sara'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); const tokenAmountAllowed = decimalsMul.mul(new ctx.web3.utils.BN('99')); yield token.instance.methods.approve(bob, tokenAmountAllowed.toString()).send({ from: owner }); yield ctx.reverts(() => token.instance.methods.transferFrom(owner, sara, tokenAmount.toString()).send({ from: bob }), '001002'); })); spec.test('throws an error when trying to transferFrom more than _from has', (ctx) => __awaiter(void 0, void 0, void 0, function* () { const token = ctx.get('token'); const owner = ctx.get('owner'); const bob = ctx.get('bob'); const sara = ctx.get('sara'); const decimalsMul = ctx.get('decimalsMul'); const tokenAmount = decimalsMul.mul(new ctx.web3.utils.BN('100')); const tokenAmountToSend = decimalsMul.mul(new ctx.web3.utils.BN('101')); yield token.instance.methods.transfer(bob, tokenAmount.toString()).send({ from: owner }); yield token.instance.methods.approve(sara, tokenAmount.toString()).send({ from: bob }); yield ctx.reverts(() => token.instance.methods.transferFrom(bob, sara, tokenAmountToSend.toString()).send({ from: sara }), '001001'); })); exports.default = spec; //# sourceMappingURL=token.test.js.map