123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
- const { expect } = require('chai');
- const { ZERO_ADDRESS, MAX_UINT256 } = constants;
- const { shouldBehaveLikeERC20 } = require('../ERC20.behavior');
- const NotAnERC20 = artifacts.require('CallReceiverMock');
- const ERC20Decimals = artifacts.require('$ERC20DecimalsMock');
- const ERC20Wrapper = artifacts.require('$ERC20Wrapper');
- contract('ERC20', function (accounts) {
- const [initialHolder, recipient, anotherAccount] = accounts;
- const name = 'My Token';
- const symbol = 'MTKN';
- const initialSupply = new BN(100);
- beforeEach(async function () {
- this.underlying = await ERC20Decimals.new(name, symbol, 9);
- await this.underlying.$_mint(initialHolder, initialSupply);
- this.token = await ERC20Wrapper.new(`Wrapped ${name}`, `W${symbol}`, this.underlying.address);
- });
- afterEach(async function () {
- expect(await this.underlying.balanceOf(this.token.address)).to.be.bignumber.equal(await this.token.totalSupply());
- });
- it('has a name', async function () {
- expect(await this.token.name()).to.equal(`Wrapped ${name}`);
- });
- it('has a symbol', async function () {
- expect(await this.token.symbol()).to.equal(`W${symbol}`);
- });
- it('has the same decimals as the underlying token', async function () {
- expect(await this.token.decimals()).to.be.bignumber.equal('9');
- });
- it('decimals default back to 18 if token has no metadata', async function () {
- const noDecimals = await NotAnERC20.new();
- const otherToken = await ERC20Wrapper.new(`Wrapped ${name}`, `W${symbol}`, noDecimals.address);
- expect(await otherToken.decimals()).to.be.bignumber.equal('18');
- });
- it('has underlying', async function () {
- expect(await this.token.underlying()).to.be.bignumber.equal(this.underlying.address);
- });
- describe('deposit', function () {
- it('valid', async function () {
- await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder });
- const { tx } = await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder });
- await expectEvent.inTransaction(tx, this.underlying, 'Transfer', {
- from: initialHolder,
- to: this.token.address,
- value: initialSupply,
- });
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: ZERO_ADDRESS,
- to: initialHolder,
- value: initialSupply,
- });
- });
- it('missing approval', async function () {
- await expectRevert(
- this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }),
- 'ERC20: insufficient allowance',
- );
- });
- it('missing balance', async function () {
- await this.underlying.approve(this.token.address, MAX_UINT256, { from: initialHolder });
- await expectRevert(
- this.token.depositFor(initialHolder, MAX_UINT256, { from: initialHolder }),
- 'ERC20: transfer amount exceeds balance',
- );
- });
- it('to other account', async function () {
- await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder });
- const { tx } = await this.token.depositFor(anotherAccount, initialSupply, { from: initialHolder });
- await expectEvent.inTransaction(tx, this.underlying, 'Transfer', {
- from: initialHolder,
- to: this.token.address,
- value: initialSupply,
- });
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: ZERO_ADDRESS,
- to: anotherAccount,
- value: initialSupply,
- });
- });
- });
- describe('withdraw', function () {
- beforeEach(async function () {
- await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder });
- await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder });
- });
- it('missing balance', async function () {
- await expectRevert(
- this.token.withdrawTo(initialHolder, MAX_UINT256, { from: initialHolder }),
- 'ERC20: burn amount exceeds balance',
- );
- });
- it('valid', async function () {
- const value = new BN(42);
- const { tx } = await this.token.withdrawTo(initialHolder, value, { from: initialHolder });
- await expectEvent.inTransaction(tx, this.underlying, 'Transfer', {
- from: this.token.address,
- to: initialHolder,
- value: value,
- });
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: initialHolder,
- to: ZERO_ADDRESS,
- value: value,
- });
- });
- it('entire balance', async function () {
- const { tx } = await this.token.withdrawTo(initialHolder, initialSupply, { from: initialHolder });
- await expectEvent.inTransaction(tx, this.underlying, 'Transfer', {
- from: this.token.address,
- to: initialHolder,
- value: initialSupply,
- });
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: initialHolder,
- to: ZERO_ADDRESS,
- value: initialSupply,
- });
- });
- it('to other account', async function () {
- const { tx } = await this.token.withdrawTo(anotherAccount, initialSupply, { from: initialHolder });
- await expectEvent.inTransaction(tx, this.underlying, 'Transfer', {
- from: this.token.address,
- to: anotherAccount,
- value: initialSupply,
- });
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: initialHolder,
- to: ZERO_ADDRESS,
- value: initialSupply,
- });
- });
- });
- describe('recover', function () {
- it('nothing to recover', async function () {
- await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder });
- await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder });
- const { tx } = await this.token.$_recover(anotherAccount);
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: ZERO_ADDRESS,
- to: anotherAccount,
- value: '0',
- });
- });
- it('something to recover', async function () {
- await this.underlying.transfer(this.token.address, initialSupply, { from: initialHolder });
- const { tx } = await this.token.$_recover(anotherAccount);
- await expectEvent.inTransaction(tx, this.token, 'Transfer', {
- from: ZERO_ADDRESS,
- to: anotherAccount,
- value: initialSupply,
- });
- });
- });
- describe('erc20 behaviour', function () {
- beforeEach(async function () {
- await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder });
- await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder });
- });
- shouldBehaveLikeERC20('ERC20', initialSupply, initialHolder, recipient, anotherAccount);
- });
- });
|