@ -23,56 +23,19 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip
} ) ;
describe ( 'transfer' , function ( ) {
describe ( 'when the recipient is not the zero address' , function ( ) {
const to = recipient ;
describe ( 'when the sender does not have enough balance' , function ( ) {
const amount = initialSupply . addn ( 1 ) ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transfer ( to , amount , { from : initialHolder } ) ,
'SafeMath: subtraction overflow'
) ;
} ) ;
} ) ;
describe ( 'when the sender has enough balance' , function ( ) {
const amount = initialSupply ;
it ( 'transfers the requested amount' , async function ( ) {
await this . token . transfer ( to , amount , { from : initialHolder } ) ;
( await this . token . balanceOf ( initialHolder ) ) . should . be . bignumber . equal ( '0' ) ;
( await this . token . balanceOf ( to ) ) . should . be . bignumber . equal ( amount ) ;
} ) ;
it ( 'emits a transfer event' , async function ( ) {
const { logs } = await this . token . transfer ( to , amount , { from : initialHolder } ) ;
expectEvent . inLogs ( logs , 'Transfer' , {
from : initialHolder ,
to : to ,
value : amount ,
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'when the recipient is the zero address' , function ( ) {
const to = ZERO _ADDRESS ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transfer ( to , initialSupply , { from : initialHolder } ) ,
` ${ errorPrefix } : transfer to the zero address `
shouldBehaveLikeERC20Transfer ( errorPrefix , initialHolder , recipient , initialSupply ,
function ( from , to , value ) {
return this . token . transfer ( to , value , { from } ) ;
}
) ;
} ) ;
} ) ;
} ) ;
describe ( 'transfer from' , function ( ) {
const spender = recipient ;
describe ( 'when the token owner is not the zero address' , function ( ) {
const tokenOwner = initialHolder ;
describe ( 'when the recipient is not the zero address' , function ( ) {
const to = anotherAccount ;
@ -81,50 +44,50 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip
await this . token . approve ( spender , initialSupply , { from : initialHolder } ) ;
} ) ;
describe ( 'when the initial hold er has enough balance' , function ( ) {
describe ( 'when the token own er has enough balance' , function ( ) {
const amount = initialSupply ;
it ( 'transfers the requested amount' , async function ( ) {
await this . token . transferFrom ( initialHold er, to , amount , { from : spender } ) ;
await this . token . transferFrom ( tokenOwn er, to , amount , { from : spender } ) ;
( await this . token . balanceOf ( initialHold er) ) . should . be . bignumber . equal ( '0' ) ;
( await this . token . balanceOf ( tokenOwn er) ) . should . be . bignumber . equal ( '0' ) ;
( await this . token . balanceOf ( to ) ) . should . be . bignumber . equal ( amount ) ;
} ) ;
it ( 'decreases the spender allowance' , async function ( ) {
await this . token . transferFrom ( initialHold er, to , amount , { from : spender } ) ;
await this . token . transferFrom ( tokenOwn er, to , amount , { from : spender } ) ;
( await this . token . allowance ( initialHold er, spender ) ) . should . be . bignumber . equal ( '0' ) ;
( await this . token . allowance ( tokenOwn er, spender ) ) . should . be . bignumber . equal ( '0' ) ;
} ) ;
it ( 'emits a transfer event' , async function ( ) {
const { logs } = await this . token . transferFrom ( initialHold er, to , amount , { from : spender } ) ;
const { logs } = await this . token . transferFrom ( tokenOwn er, to , amount , { from : spender } ) ;
expectEvent . inLogs ( logs , 'Transfer' , {
from : initialHold er,
from : tokenOwn er,
to : to ,
value : amount ,
} ) ;
} ) ;
it ( 'emits an approval event' , async function ( ) {
const { logs } = await this . token . transferFrom ( initialHold er, to , amount , { from : spender } ) ;
const { logs } = await this . token . transferFrom ( tokenOwn er, to , amount , { from : spender } ) ;
expectEvent . inLogs ( logs , 'Approval' , {
owner : initialHold er,
owner : tokenOwn er,
spender : spender ,
value : await this . token . allowance ( initialHold er, spender ) ,
value : await this . token . allowance ( tokenOwn er, spender ) ,
} ) ;
} ) ;
} ) ;
describe ( 'when the initial hold er does not have enough balance' , function ( ) {
describe ( 'when the token own er does not have enough balance' , function ( ) {
const amount = initialSupply . addn ( 1 ) ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transferFrom (
initialHold er, to , amount , { from : spender } ) , 'SafeMath: subtraction overflow'
tokenOwn er , to , amount , { from : spender } ) , 'SafeMath: subtraction overflow'
) ;
} ) ;
} ) ;
@ -132,25 +95,25 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip
describe ( 'when the spender does not have enough approved balance' , function ( ) {
beforeEach ( async function ( ) {
await this . token . approve ( spender , initialSupply . subn ( 1 ) , { from : initialHold er } ) ;
await this . token . approve ( spender , initialSupply . subn ( 1 ) , { from : tokenOwn er } ) ;
} ) ;
describe ( 'when the initial hold er has enough balance' , function ( ) {
describe ( 'when the token own er has enough balance' , function ( ) {
const amount = initialSupply ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transferFrom (
initialHold er, to , amount , { from : spender } ) , 'SafeMath: subtraction overflow'
tokenOwn er , to , amount , { from : spender } ) , 'SafeMath: subtraction overflow'
) ;
} ) ;
} ) ;
describe ( 'when the initial hold er does not have enough balance' , function ( ) {
describe ( 'when the token own er does not have enough balance' , function ( ) {
const amount = initialSupply . addn ( 1 ) ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transferFrom (
initialHold er, to , amount , { from : spender } ) , 'SafeMath: subtraction overflow'
tokenOwn er , to , amount , { from : spender } ) , 'SafeMath: subtraction overflow'
) ;
} ) ;
} ) ;
@ -162,12 +125,25 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip
const to = ZERO _ADDRESS ;
beforeEach ( async function ( ) {
await this . token . approve ( spender , amount , { from : initialHolder } ) ;
await this . token . approve ( spender , amount , { from : tokenOwner } ) ;
} ) ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transferFrom (
tokenOwner , to , amount , { from : spender } ) , ` ${ errorPrefix } : transfer to the zero address `
) ;
} ) ;
} ) ;
} ) ;
describe ( 'when the token owner is the zero address' , function ( ) {
const amount = 0 ;
const tokenOwner = ZERO _ADDRESS ;
const to = recipient ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( this . token . transferFrom (
initialHolder , to , amount , { from : spender } ) , ` ${ errorPrefix } : transfer to the zero address `
tokenOwn er, to , amount , { from : spender } ) , ` ${ errorPrefix } : transfer from the zero address `
) ;
} ) ;
} ) ;
@ -182,6 +158,72 @@ function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recip
} ) ;
}
function shouldBehaveLikeERC20Transfer ( errorPrefix , from , to , balance , transfer ) {
describe ( 'when the recipient is not the zero address' , function ( ) {
describe ( 'when the sender does not have enough balance' , function ( ) {
const amount = balance . addn ( 1 ) ;
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( transfer . call ( this , from , to , amount ) ,
'SafeMath: subtraction overflow'
) ;
} ) ;
} ) ;
describe ( 'when the sender transfers all balance' , function ( ) {
const amount = balance ;
it ( 'transfers the requested amount' , async function ( ) {
await transfer . call ( this , from , to , amount ) ;
( await this . token . balanceOf ( from ) ) . should . be . bignumber . equal ( '0' ) ;
( await this . token . balanceOf ( to ) ) . should . be . bignumber . equal ( amount ) ;
} ) ;
it ( 'emits a transfer event' , async function ( ) {
const { logs } = await transfer . call ( this , from , to , amount ) ;
expectEvent . inLogs ( logs , 'Transfer' , {
from ,
to ,
value : amount ,
} ) ;
} ) ;
} ) ;
describe ( 'when the sender transfers zero tokens' , function ( ) {
const amount = new BN ( '0' ) ;
it ( 'transfers the requested amount' , async function ( ) {
await transfer . call ( this , from , to , amount ) ;
( await this . token . balanceOf ( from ) ) . should . be . bignumber . equal ( balance ) ;
( await this . token . balanceOf ( to ) ) . should . be . bignumber . equal ( '0' ) ;
} ) ;
it ( 'emits a transfer event' , async function ( ) {
const { logs } = await transfer . call ( this , from , to , amount ) ;
expectEvent . inLogs ( logs , 'Transfer' , {
from ,
to ,
value : amount ,
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'when the recipient is the zero address' , function ( ) {
it ( 'reverts' , async function ( ) {
await shouldFail . reverting . withMessage ( transfer . call ( this , from , ZERO _ADDRESS , balance ) ,
` ${ errorPrefix } : transfer to the zero address `
) ;
} ) ;
} ) ;
}
function shouldBehaveLikeERC20Approve ( errorPrefix , owner , spender , supply , approve ) {
describe ( 'when the spender is not the zero address' , function ( ) {
describe ( 'when the sender has enough balance' , function ( ) {
@ -264,5 +306,6 @@ function shouldBehaveLikeERC20Approve (errorPrefix, owner, spender, supply, appr
module . exports = {
shouldBehaveLikeERC20 ,
shouldBehaveLikeERC20Transfer ,
shouldBehaveLikeERC20Approve ,
} ;