123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /* 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()
- })
- })
|