import { expect , use } from 'chai' ; import { BigNumberish , providers , Wallet } from 'ethers' ; import { solidity } from 'ethereum-waffle' ; import { initialSupply , setupTrueGold } from 'fixtures/trueGold' ; import { toAddress , WalletOrAddress } from 'utils' ; import { loadFixture } from 'fixtures/beforeEachWithFixture' ; import { TrueGold } from 'contracts' ; use ( solidity ) ; describe ( 'TrueGold' , ( ) => { const redemptionAddress = '0x0000000000000000000000000000000000074D72' ; let deployer ; let initialHolder ; let secondAccount ; let token ; function approve ( tokenOwner , spender , amount ) { const asTokenOwner = token . connect ( tokenOwner ) ; return asTokenOwner . approve ( toAddress ( spender ) , amount ) ; } beforeEach ( async ( ) => { ( { deployer , initialHolder , secondAccount , token } = await loadFixture ( setupTrueGold ) ) ; } ) ; describe ( 'has standard token properties' , ( ) => { it ( 'name' , async ( ) => { expect ( await token . name ( ) ) . to . eq ( 'TrueGold' ) ; } ) ; it ( 'symbol' , async ( ) => { expect ( await token . symbol ( ) ) . to . eq ( 'TGOLD' ) ; } ) ; it ( 'decimals' , async ( ) => { expect ( await token . decimals ( ) ) . to . eq ( 6 ) ; } ) ; } ) ; describe ( 'burn amount restrictions' , ( ) => { const initialBalance = initialSupply ; let tokenOwner ; let burner ; beforeEach ( async ( ) => { tokenOwner = initialHolder ; burner = secondAccount ; } ) ; function shouldRespectBurnRestrictions ( burn ) { describe ( 'when burn amount is not a multiple of 12,441,000' , ( ) => { function reverts ( amount ) { it ( 'reverts' , async ( ) => { await expect ( burn ( amount ) ) . to . be . revertedWith ( 'TrueGold: burn amount is not a multiple of 12,441,000' ) ; } ) ; } describe ( 'for 8,000,000 amount' , ( ) => { reverts ( 8000000 ) ; } ) ; describe ( 'for 12,441,001 amount' , ( ) => { reverts ( 12441001 ) ; } ) ; } ) ; describe ( 'when burn amount is a multiple of 12,441,000' , ( ) => { function successfullyBurns ( amount ) { it ( 'burns the requested amount' , async ( ) => { await burn ( amount ) ; expect ( await token . balanceOf ( tokenOwner . address ) ) . to . eq ( initialBalance . sub ( amount ) ) ; expect ( await token . totalSupply ( ) ) . to . eq ( initialSupply . sub ( amount ) ) ; } ) ; } describe ( 'for a zero amount' , ( ) => { successfullyBurns ( 0 ) ; } ) ; describe ( 'for 12,441,000 amount' , ( ) => { successfullyBurns ( 12441000 ) ; } ) ; describe ( 'for 37,323,000 amount' , ( ) => { successfullyBurns ( 37323000 ) ; } ) ; } ) ; } describe ( 'burn' , ( ) => { shouldRespectBurnRestrictions ( amount => token . connect ( tokenOwner ) . burn ( amount ) ) ; } ) ; describe ( 'burnFrom' , ( ) => { beforeEach ( async ( ) => { await approve ( tokenOwner , burner , 37323000 ) ; } ) ; shouldRespectBurnRestrictions ( amount => token . connect ( burner ) . burnFrom ( tokenOwner . address , amount ) ) ; } ) ; describe ( 'transfer' , ( ) => { shouldRespectBurnRestrictions ( amount => token . connect ( tokenOwner ) . transfer ( redemptionAddress , amount ) ) ; } ) ; describe ( 'transferFrom' , ( ) => { beforeEach ( async ( ) => { await approve ( tokenOwner , burner , 37323000 ) ; } ) ; shouldRespectBurnRestrictions ( amount => token . connect ( burner ) . transferFrom ( tokenOwner . address , redemptionAddress , amount ) ) ; } ) ; } ) ; describe ( 'setBurnBounds' , ( ) => { function setBurnBounds ( caller , minAmount , maxAmount ) { return token . connect ( caller ) . setBurnBounds ( minAmount , maxAmount ) ; } let owner ; beforeEach ( ( ) => { owner = deployer ; } ) ; describe ( 'when given bounds are multiples of 12,441,000' , ( ) => { it ( 'sets the new burn bounds' , async ( ) => { await setBurnBounds ( owner , 12441000 , 12441000 * 2 ) ; expect ( await token . burnMin ( ) ) . to . eq ( 12441000 ) ; expect ( await token . burnMax ( ) ) . to . eq ( 12441000 * 2 ) ; } ) ; } ) ; describe ( 'when min amount is not a multiple of 12,441,000' , ( ) => { it ( 'reverts' , async ( ) => { await expect ( setBurnBounds ( owner , 8000000 , 12441000 ) ) . to . be . revertedWith ( 'TrueGold: min amount is not a multiple of 12,441,000' ) ; } ) ; } ) ; describe ( 'when max amount is not a multiple of 12,441,000' , ( ) => { it ( 'reverts' , async ( ) => { await expect ( setBurnBounds ( owner , 12441000 , 20000000 ) ) . to . be . revertedWith ( 'TrueGold: max amount is not a multiple of 12,441,000' ) ; } ) ; } ) ; } ) ; } ) ;