Last active
February 5, 2018 10:18
-
-
Save safead/1f1b78550f031df73fe0308366f10487 to your computer and use it in GitHub Desktop.
SAFE token truffle tests gist (improved ConsenSys tests)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
SAFE token contract: https://gist.github.com/safead/17f523bad49327ab5a706606757da51b