torn-token/test/torn.test.js

206 lines
7.2 KiB
JavaScript

/* global artifacts, web3, contract */
require('chai').use(require('bn-chai')(web3.utils.BN)).use(require('chai-as-promised')).should()
const { takeSnapshot, revertSnapshot } = require('../scripts/ganacheHelper')
const { PermitSigner } = require('../lib/Permit')
const { toBN, BN } = require('web3-utils')
const Torn = artifacts.require('./TORNMock.sol')
contract('Torn', (accounts) => {
let torn
const governance = accounts[3]
const mining = accounts[4]
const airdrop = accounts[5]
let snapshotId
const owner = accounts[0]
const ownerPrivateKey = '0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3'
const spender = accounts[1]
// eslint-disable-next-line no-unused-vars
const spenderPrivateKey = '0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f'
// eslint-disable-next-line no-unused-vars
const recipient = accounts[2]
// eslint-disable-next-line no-unused-vars
const recipientPrivateKey = '0x0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1'
const value = toBN(10 ** 18)
let domain
let chainId
const cap = toBN(10000000).mul(toBN(10 ** 18))
let currentTime
const thirtyDays = 30 * 24 * 3600
before(async () => {
chainId = await web3.eth.net.getId()
torn = await Torn.new(governance, thirtyDays, [
{ to: mining, amount: '0' },
{ to: airdrop, amount: cap.toString() },
])
currentTime = await torn.blockTimestamp()
await torn.transfer(owner, cap.div(toBN(2)), { from: airdrop })
await torn.setChainId(chainId)
await torn.setFakeTimestamp(currentTime)
const blockTimestamp = await torn.blockTimestamp()
blockTimestamp.should.be.eq.BN(toBN(currentTime))
domain = {
name: await torn.name(),
version: '1',
chainId,
verifyingContract: torn.address,
}
snapshotId = await takeSnapshot()
})
describe('#constructor', () => {
it('transfers ownership to governance', async () => {
const ownerFromContract = await torn.governance()
ownerFromContract.should.be.equal(governance)
;(await torn.allowedTransferee(governance)).should.be.true
;(await torn.allowedTransferee(mining)).should.be.true
;(await torn.allowedTransferee(airdrop)).should.be.true
;(await torn.allowedTransferee(owner)).should.be.false
})
})
describe('pausable', () => {
it('transfers disabled by default', async () => {
await torn.transfer(accounts[1], 1, { from: spender }).should.be.rejectedWith('TORN: paused')
})
it('can only transfer to governance and mining', async () => {
await torn.transfer(governance, 1).should.be.fulfilled
await torn.transfer(mining, 1).should.be.fulfilled
await torn.transfer(accounts[5], 1, { from: mining }).should.be.fulfilled
})
it('can transfer after governace decision', async () => {
await torn.transfer(mining, 10).should.be.fulfilled
await torn.transfer(recipient, 5, { from: mining }).should.be.fulfilled
await torn.transfer(accounts[9], 1, { from: recipient }).should.be.rejectedWith('TORN: paused')
await torn
.changeTransferability(true, { from: governance })
.should.be.rejectedWith('TORN: cannot change transferability yet')
await torn.setFakeTimestamp(currentTime + thirtyDays + 1)
await torn.changeTransferability(true, { from: governance })
await torn.transfer(accounts[9], 1, { from: recipient })
const balance = await torn.balanceOf(accounts[9])
balance.should.be.eq.BN(toBN(1))
})
})
describe('#permit', () => {
it('permitSigner class should work', async () => {
const args = {
owner,
spender,
value,
nonce: 0,
deadline: new BN('123123123123123'),
}
const permitSigner = new PermitSigner(domain, args)
// const message = permitSigner.getPayload()
// console.log('message', JSON.stringify(message));
// Generate the signature in place
const privateKey = '0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c'
const address = '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b'
const signature = await permitSigner.getSignature(privateKey)
const signer = await permitSigner.getSignerAddress(args, signature.hex)
address.should.be.equal(signer)
})
it('calls approve if signature is valid', async () => {
const chainIdFromContract = await torn.chainId()
chainIdFromContract.should.be.eq.BN(new BN(domain.chainId))
const args = {
owner,
spender,
value,
nonce: 0,
deadline: new BN(currentTime + thirtyDays),
}
const permitSigner = new PermitSigner(domain, args)
const signature = await permitSigner.getSignature(ownerPrivateKey)
const signer = await permitSigner.getSignerAddress(args, signature.hex)
signer.should.be.equal(owner)
const allowanceBefore = await torn.allowance(owner, spender)
await torn.permit(
args.owner,
args.spender,
args.value.toString(),
args.deadline.toString(),
signature.v,
signature.r,
signature.s,
{ from: owner },
)
const allowanceAfter = await torn.allowance(owner, spender)
allowanceAfter.should.be.eq.BN(toBN(allowanceBefore).add(args.value))
})
it('reverts if signature is corrupted', async () => {
const args = {
owner,
spender,
value,
nonce: 0,
deadline: new BN(currentTime + thirtyDays),
}
const permitSigner = new PermitSigner(domain, args)
const signature = await permitSigner.getSignature(ownerPrivateKey)
signature.r = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
const allowanceBefore = await torn.allowance(owner, spender)
await torn
.permit(
args.owner,
args.spender,
args.value.toString(),
args.deadline.toString(),
signature.v,
signature.r,
signature.s,
{ from: owner },
)
.should.be.rejectedWith('ECDSA: invalid signature')
const allowanceAfter = await torn.allowance(owner, spender)
allowanceAfter.should.be.eq.BN(allowanceBefore)
})
it('reverts if signature is expired', async () => {
const args = {
owner,
spender,
value,
nonce: 0,
deadline: new BN('1593388800'), // 06/29/2020 @ 12:00am (UTC)
}
const permitSigner = new PermitSigner(domain, args)
const signature = await permitSigner.getSignature(ownerPrivateKey)
const allowanceBefore = await torn.allowance(owner, spender)
await torn
.permit(
args.owner,
args.spender,
args.value.toString(),
args.deadline.toString(),
signature.v,
signature.r,
signature.s,
{ from: owner },
)
.should.be.rejectedWith('ERC20Permit: expired deadline')
const allowanceAfter = await torn.allowance(owner, spender)
allowanceAfter.should.be.eq.BN(BN(allowanceBefore))
})
})
afterEach(async () => {
await revertSnapshot(snapshotId.result)
// eslint-disable-next-line require-atomic-updates
snapshotId = await takeSnapshot()
})
})