Skip to content

Instantly share code, notes, and snippets.

@safead
Last active February 5, 2018 10:18
Show Gist options
  • Save safead/1f1b78550f031df73fe0308366f10487 to your computer and use it in GitHub Desktop.
Save safead/1f1b78550f031df73fe0308366f10487 to your computer and use it in GitHub Desktop.
SAFE token truffle tests gist (improved ConsenSys tests)
'use strict';
const SAFEToken = artifacts.require('./SAFEToken.sol');
const MaxBN = big(2).pow(255).plus(big(2).pow(255).minus(1));
const expectThrow = async (promise) => {
const errMsg = 'Expected throw not received';
try{
await promise;
}catch (err){
assert(err.toString().includes('Exception while processing transaction: revert'), errMsg);
return;
}
assert.fail(errMsg);
}
function findInLogs(logs, eventName, address){
for(var i = 0; i < logs.length; i++){
if(logs[i]['event'] !== eventName) continue;
if(address && logs[i].args['_to'] !== address) continue;
return logs[i].args;
}
return null;
}
function big(val){
return new web3.BigNumber(val);
}
var Contract, Contract2, transLog, value, advancedLog = true;
contract('SAFEToken', (accounts) =>{
console.log("contract connected, accounts\n\n", accounts);
afterEach(() => {
this.res && this.res.receipt && advancedLog && console.log("\t[ gas cost: " + this.res.receipt.gasUsed + " ]");
delete(this.res);
});
before(async () => {
Contract = await SAFEToken.new(10000, 'Some Coin', 'WWW', 8);
});
describe('Initialization', () => {
it('check initial balance of 10000 for the owner: accounts[0]: ' + accounts[0], async () => {
value = await Contract.balanceOf.call(accounts[0]);
assert.strictEqual(value.toNumber(), 10000);
});
it('test correct setting of vanity information', async () => {
this.res = await Contract.name.call();
assert.strictEqual(this.res, 'Some Coin');
this.res = await Contract.decimals.call();
assert.strictEqual(this.res.toNumber(), 8);
this.res = await Contract.symbol.call();
assert.strictEqual(this.res, 'WWW');
});
it('should succeed in creating a contract with 2^256 - 1 (max) tokens', async () => {
Contract2 = await SAFEToken.new(MaxBN, 'Other acc', 'OTH', 18, { from: accounts[9] });
this.res = Contract2;
value = await this.res.totalSupply();
assert(value.toNumber(), MaxBN, 'result is not correct');
});
});
describe('Owner-only functions', () => {
it('change info: change token name & abbr, check UpdatedTokenInformation event and new values', async () => {
this.res = await Contract.setTokenInformation('Mail Coin', 'SAFE', 18);
transLog = findInLogs(this.res.logs, 'UpdatedTokenInformation');
assert.strictEqual(transLog._newName, 'Mail Coin');
assert.strictEqual(transLog._newSymbol, 'SAFE');
assert.strictEqual(transLog._newDecimals.toNumber(), 18);
});
it('change info: test token changes', async () => {
this.res = await Contract.name.call();
assert.strictEqual(this.res, 'Mail Coin');
this.res = await Contract.decimals.call();
assert.strictEqual(this.res.toNumber(), 18);
this.res = await Contract.symbol.call();
assert.strictEqual(this.res, 'SAFE');
});
it('ownership: change to 0x0 address (should revert)', async () => {
this.res = await Contract.changeOwner(0x0);
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[0]);
assert.strictEqual(transLog._errorCode.toNumber(), 1);
});
it('ownership: change from non-owner address (should revert)', async () => { expectThrow(
Contract.changeOwner(accounts[1], {from: accounts[1]})
)});
it('ownership: change to accounts[1]', async () => {
this.res = await Contract.changeOwner(accounts[1]);
transLog = findInLogs(this.res.logs, 'OwnershipTransferred');
assert.strictEqual(transLog._previousOwner, accounts[0]);
assert.strictEqual(transLog._newOwner, accounts[1]);
});
it('finish minting: from non-authorized address (should revert)', async () => { expectThrow(
Contract.finishMinting({ from: accounts[0] })
)});
it('finish minting: stop mint forever', async () => {
this.res = await Contract.finishMinting({ from: accounts[1] });
transLog = findInLogs(this.res.logs, 'MintFinished');
assert.notEqual(transLog, null);
});
it('mint: try to mint tokens from owner address (should revert)', async () => { expectThrow(
Contract.mint([accounts[1]], [1])
)});
it('mint: try to mint tokens from non-authorized address (should revert)', async () => { expectThrow(
Contract.mint([accounts[1]], [1], {from: accounts[1]})
)});
it('ownership: change back to accounts[0]', async () => {
this.res = await Contract.changeOwner(accounts[0], {from: accounts[1]});
transLog = findInLogs(this.res.logs, 'OwnershipTransferred');
assert.strictEqual(transLog._previousOwner, accounts[1]);
assert.strictEqual(transLog._newOwner, accounts[0]);
});
});
describe('Transfers', () => {
it('try to transfer when transfers are blocked (should revert)', async () => {
this.res = await Contract.transfer(accounts[1], 1);
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[0]);
assert.strictEqual(transLog._errorCode.toNumber(), 7);
});
it('try to transferFrom when transfers are blocked (should revert)', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[1], 1);
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[0]);
assert.strictEqual(transLog._errorCode.toNumber(), 7);
});
it('owner only: set transfers granted', async () => {
this.res = await Contract.allowTransfers();
transLog = findInLogs(this.res.logs, 'TransfersAreAllowed');
assert(typeof transLog === 'object');
this.res = await Contract2.allowTransfers( { from: accounts[9] } );
transLog = findInLogs(this.res.logs, 'TransfersAreAllowed');
assert(typeof transLog === 'object');
});
it('should transfer 10000 to accounts[1] from accounts[0] having 10000', async () => {
this.res = await Contract.transfer(accounts[1], 10000);
value = await Contract.balanceOf.call(accounts[1]);
assert.strictEqual(value.toNumber(), 10000);
});
it('try to transfer 1 to accounts[1] from accounts[0] having 0 (should revert)', async () => {
this.res = await Contract.transfer(accounts[1], 1);
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[0]);
assert.strictEqual(transLog._errorCode.toNumber(), 2);
});
it('should handle zero-transfers normally', async () => {
this.res = await Contract.transfer(accounts[1], 0);
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[1]);
assert.strictEqual(transLog._value.toNumber(), 0);
});
it('try to transfer to account 0x0 (should revert)', async () => {
this.res = await Contract.transfer(0x0, 1);
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[0]);
assert.strictEqual(transLog._errorCode.toNumber(), 1);
});
it('transfer max amount 2^256 - 1', async () => {
this.res = await Contract2.transfer(accounts[0], MaxBN, { from: accounts[9] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[9]);
assert.strictEqual(transLog._to, accounts[0]);
assert.strictEqual(transLog._value.toNumber(), MaxBN.toNumber());
});
it('accounts[0] must now have maximum value 2^256 - 1', async () => {
value = await Contract2.balanceOf.call(accounts[0]);
assert.strictEqual(value.toNumber(), MaxBN.toNumber());
});
it('ether transfer to token contract (should revert)', async () => { expectThrow(
Contract.send(web3.toWei(0.5, 'ether'), {from: accounts[1]})
)});
});
describe('Approvals', () => {
before(async () => {
Contract = await SAFEToken.new(10000, 'SAFE Coin', 'SAFE0', 18, { from: accounts[0] });
await Contract.allowTransfers();
});
it('approve to withdrow tokens from accounts[0] (100 to accounts[1] & 200 to accounts[2] & UNLIMITED to accounts[3])', async () => {
this.res = await Contract.approve(accounts[1], 100);
transLog = findInLogs(this.res.logs, 'Approval');
assert.strictEqual(transLog._owner, accounts[0]);
assert.strictEqual(transLog._spender, accounts[1]);
assert.strictEqual(transLog._value.toNumber(), 100);
this.res = await Contract.approve(accounts[2], 200);
transLog = findInLogs(this.res.logs, 'Approval');
assert.strictEqual(transLog._owner, accounts[0]);
assert.strictEqual(transLog._spender, accounts[2]);
assert.strictEqual(transLog._value.toNumber(), 200);
this.res = await Contract.approve(accounts[3], MaxBN);
transLog = findInLogs(this.res.logs, 'Approval');
assert.strictEqual(transLog._owner, accounts[0]);
assert.strictEqual(transLog._spender, accounts[3]);
assert.strictEqual(transLog._value.toNumber(), MaxBN.toNumber());
});
it('check allowance', async () => {
value = await Contract.allowance.call(accounts[0], accounts[1]);
assert.strictEqual(value.toNumber(), 100);
value = await Contract.allowance.call(accounts[0], accounts[2]);
assert.strictEqual(value.toNumber(), 200);
value = await Contract.allowance.call(accounts[0], accounts[3]);
assert.strictEqual(value.toNumber(), MaxBN.toNumber());
});
it('withdraws from accounts[0] (20 to accounts[1] & 150 to accounts[2] & 1000 to accounts[3])', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[1], 20, { from: accounts[1] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[1]);
assert.strictEqual(transLog._value.toNumber(), 20);
this.res = await Contract.transferFrom(accounts[0], accounts[2], 150, { from: accounts[2] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[2]);
assert.strictEqual(transLog._value.toNumber(), 150);
this.res = await Contract.transferFrom(accounts[0], accounts[3], 1000, { from: accounts[3] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[3]);
assert.strictEqual(transLog._value.toNumber(), 1000);
});
it('check allowance left', async () => {
this.res = await Contract.allowance.call(accounts[0], accounts[1]);
assert.strictEqual(this.res.toNumber(), 80);
this.res = await Contract.allowance.call(accounts[0], accounts[2]);
assert.strictEqual(this.res.toNumber(), 50);
this.res = await Contract.allowance.call(accounts[0], accounts[3]);
assert.strictEqual(this.res.toNumber(), MaxBN.toNumber());
});
it('check accounts[0], accounts[1], accounts[2], accounts[3] balances', async () => {
value = await Contract.balanceOf.call(accounts[0]);
assert.strictEqual(value.toNumber(), 8830);
value = await Contract.balanceOf.call(accounts[1]);
assert.strictEqual(value.toNumber(), 20);
value = await Contract.balanceOf.call(accounts[2]);
assert.strictEqual(value.toNumber(), 150);
value = await Contract.balanceOf.call(accounts[3]);
assert.strictEqual(value.toNumber(), 1000);
});
it('withdraws 100 from accounts[0] to accounts[1] (should revert)', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[1], 100, { from: accounts[1] });
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[1]);
assert.strictEqual(transLog._errorCode.toNumber(), 3);
});
it('withdraws from accounts[0] (80 to accounts[1] & 50 to accounts[2] & 5000 to accounts[3])', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[1], 80, { from: accounts[1] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[1]);
assert.strictEqual(transLog._value.toNumber(), 80);
this.res = await Contract.transferFrom(accounts[0], accounts[2], 50, { from: accounts[2] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[2]);
assert.strictEqual(transLog._value.toNumber(), 50);
this.res = await Contract.transferFrom(accounts[0], accounts[3], 5000, { from: accounts[3] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[3]);
assert.strictEqual(transLog._value.toNumber(), 5000);
});
it('check allowance left', async () => {
this.res = await Contract.allowance.call(accounts[0], accounts[1]);
assert.strictEqual(this.res.toNumber(), 0);
this.res = await Contract.allowance.call(accounts[0], accounts[2]);
assert.strictEqual(this.res.toNumber(), 0);
this.res = await Contract.allowance.call(accounts[0], accounts[3]);
assert.strictEqual(this.res.toNumber(), MaxBN.toNumber());
});
it('withdrow 3600 from accounts[0] by UNLIMITED accounts[3] to accounts[2]', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[2], 3600, { from: accounts[3] });
transLog = findInLogs(this.res.logs, 'Transfer');
assert.strictEqual(transLog._from, accounts[0]);
assert.strictEqual(transLog._to, accounts[2]);
assert.strictEqual(transLog._value.toNumber(), 3600);
});
it('withdraws 100 from accounts[0] to accounts[3] from accounts[1] (should revert)', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[3], 100, { from: accounts[1] });
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[1]);
assert.strictEqual(transLog._errorCode.toNumber(), 3);
});
it('accounts[0] balances should be 100', async () => {
value = await Contract.balanceOf.call(accounts[0]);
assert.strictEqual(value.toNumber(), 100);
});
it('withdraws 101 from accounts[0] by UNLIMITED accounts[3] to accounts[1]', async () => {
this.res = await Contract.transferFrom(accounts[0], accounts[1], 101, { from: accounts[3] });
transLog = findInLogs(this.res.logs, 'Error');
assert.strictEqual(transLog._self, accounts[3]);
assert.strictEqual(transLog._errorCode.toNumber(), 2);
});
});
});
@safead
Copy link
Author

safead commented Jan 30, 2018

@safead
Copy link
Author

safead commented Jan 30, 2018

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment