Skip to content

Commit

Permalink
Add ERC20 and ERC777 fixed supply presets #2377 (#2399)
Browse files Browse the repository at this point in the history
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
  • Loading branch information
ashwinYardi and frangio authored Dec 2, 2020
1 parent 5748034 commit 883116e
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411))
* `EIP712`: added helpers to verify EIP712 typed data signatures on chain. ([#2418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2418))
* Presets: added token presets with preminted fixed supply `ERC20PresetFixedSupply` and `ERC777PresetFixedSupply`. ([#2399](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2399))
* `Address`: added `functionDelegateCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333))

## 3.3.0 (2020-11-26)
Expand Down
30 changes: 30 additions & 0 deletions contracts/presets/ERC20PresetFixedSupply.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;

import "../token/ERC20/ERC20Burnable.sol";

/**
* @dev {ERC20} token, including:
*
* - Preminted initial supply
* - Ability for holders to burn (destroy) their tokens
* - No access control mechanism (for minting/pausing) and hence no governance
*
* This contract uses {ERC20Burnable} to include burn capabilities - head to
* its documentation for details.
*/
contract ERC20PresetFixedSupply is ERC20Burnable {
/**
* @dev Mints `initialSupply` amount of token and transfers them to `owner`.
*
* See {ERC20-constructor}.
*/
constructor(
string memory name,
string memory symbol,
uint256 initialSupply,
address owner
) public ERC20(name, symbol) {
_mint(owner, initialSupply);
}
}
27 changes: 27 additions & 0 deletions contracts/presets/ERC777PresetFixedSupply.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;

import "../token/ERC777/ERC777.sol";

/**
* @dev {ERC777} token, including:
*
* - Preminted initial supply
* - No access control mechanism (for minting/pausing) and hence no governance
*/
contract ERC777PresetFixedSupply is ERC777 {
/**
* @dev Mints `initialSupply` amount of token and transfers them to `owner`.
*
* See {ERC777-constructor}.
*/
constructor(
string memory name,
string memory symbol,
address[] memory defaultOperators,
uint256 initialSupply,
address owner
) public ERC777(name, symbol, defaultOperators) {
_mint(owner, initialSupply, "", "");
}
}
4 changes: 4 additions & 0 deletions contracts/presets/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ TIP: Intermediate and advanced users can use these as starting points when writi
{{ERC721PresetMinterPauserAutoId}}

{{ERC1155PresetMinterPauser}}

{{ERC20PresetFixedSupply}}

{{ERC777PresetFixedSupply}}
42 changes: 42 additions & 0 deletions test/presets/ERC20PresetFixedSupply.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const { BN, constants, expectEvent } = require('@openzeppelin/test-helpers');
const { ZERO_ADDRESS } = constants;

const { expect } = require('chai');

const ERC20PresetFixedSupply = artifacts.require('ERC20PresetFixedSupply');

contract('ERC20PresetFixedSupply', function (accounts) {
const [deployer, owner] = accounts;

const name = 'PresetFixedSupply';
const symbol = 'PFS';

const initialSupply = new BN('50000');
const amount = new BN('10000');

before(async function () {
this.token = await ERC20PresetFixedSupply.new(name, symbol, initialSupply, owner, { from: deployer });
});

it('deployer has the balance equal to initial supply', async function () {
expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialSupply);
});

it('total supply is equal to initial supply', async function () {
expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply);
});

describe('burning', function () {
it('holders can burn their tokens', async function () {
const remainingBalance = initialSupply.sub(amount);
const receipt = await this.token.burn(amount, { from: owner });
expectEvent(receipt, 'Transfer', { from: owner, to: ZERO_ADDRESS, value: amount });
expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(remainingBalance);
});

it('decrements totalSupply', async function () {
const expectedSupply = initialSupply.sub(amount);
expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply);
});
});
});
49 changes: 49 additions & 0 deletions test/presets/ERC777PresetFixedSupply.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const { BN, singletons } = require('@openzeppelin/test-helpers');

const { expect } = require('chai');

const ERC777PresetFixedSupply = artifacts.require('ERC777PresetFixedSupply');

contract('ERC777PresetFixedSupply', function (accounts) {
const [registryFunder, owner, defaultOperatorA, defaultOperatorB, anyone] = accounts;

const initialSupply = new BN('10000');
const name = 'ERC777Preset';
const symbol = '777P';

const defaultOperators = [defaultOperatorA, defaultOperatorB];

before(async function () {
await singletons.ERC1820Registry(registryFunder);
});

beforeEach(async function () {
this.token = await ERC777PresetFixedSupply.new(name, symbol, defaultOperators, initialSupply, owner);
});

it('returns the name', async function () {
expect(await this.token.name()).to.equal(name);
});

it('returns the symbol', async function () {
expect(await this.token.symbol()).to.equal(symbol);
});

it('returns the default operators', async function () {
expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators);
});

it('default operators are operators for all accounts', async function () {
for (const operator of defaultOperators) {
expect(await this.token.isOperatorFor(operator, anyone)).to.equal(true);
}
});

it('returns the total supply equal to initial supply', async function () {
expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply);
});

it('returns the balance of owner equal to initial supply', async function () {
expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialSupply);
});
});

0 comments on commit 883116e

Please sign in to comment.