From c3a2a5d88ad37b63e9545e61c675086b41cebeea Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 14:22:23 -0400 Subject: [PATCH 01/19] Create npm-gulp.yml Use to verify contract on polygonscan. To ABI-encode constructor arguments for the DollarToken contract --- .github/workflows/npm-gulp.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/npm-gulp.yml diff --git a/.github/workflows/npm-gulp.yml b/.github/workflows/npm-gulp.yml new file mode 100644 index 000000000..572444eab --- /dev/null +++ b/.github/workflows/npm-gulp.yml @@ -0,0 +1,28 @@ +name: NodeJS with Gulp + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [14.x, 16.x, 18.x] + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Build + run: | + npm install + gulp From 1565753a5ead7de600d0e097ce2324692b0d4230 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:36:16 -0400 Subject: [PATCH 02/19] Create abi-encode.yml To ABI-encode constructor arguments for the DollarToken contract --- github/workflows/abi-encode.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 github/workflows/abi-encode.yml diff --git a/github/workflows/abi-encode.yml b/github/workflows/abi-encode.yml new file mode 100644 index 000000000..2e6930667 --- /dev/null +++ b/github/workflows/abi-encode.yml @@ -0,0 +1,25 @@ +name: ABI Encode Constructor Arguments + +on: + push: + branches: + - main + +jobs: + abi_encode: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: 14 + + - name: Install dependencies + run: npm install + + - name: ABI Encode + run: npm run abi-encode From 30acf61a836de94d93d8e1a5193ddf2a1b58d11f Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:44:12 -0400 Subject: [PATCH 03/19] Create abi-encode.js --- scripts/abi-encode.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 scripts/abi-encode.js diff --git a/scripts/abi-encode.js b/scripts/abi-encode.js new file mode 100644 index 000000000..04f344c6b --- /dev/null +++ b/scripts/abi-encode.js @@ -0,0 +1,11 @@ +const Web3 = require('web3'); + +// Replace the following values with your contract's constructor arguments +const constructorArgs = [ + 'c4988f9629a4f68fe642f3f9c2407c6b4d723a38' +]; + +const web3 = new Web3(); +const encodedArgs = web3.eth.abi.encodeParameters(['address'], constructorArgs); + +console.log(`ABI-encoded constructor arguments: ${encodedArgs}`); From d448450fa69d9a152c0ccb91eb9be2ec0aa2ce78 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:45:59 -0400 Subject: [PATCH 04/19] Create npm-publish.yml --- .github/workflows/npm-publish.yml | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/npm-publish.yml diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 000000000..6cdebafb6 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,33 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages + +name: Node.js Package + +on: + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + - run: npm ci + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.npm_token}} From 81317360296ebd7dadd7b778d5b4098101957363 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:49:29 -0400 Subject: [PATCH 05/19] Create abi-encode.yml To ABI-encode constructor arguments for the DollarToken contract --- .github/workflows/abi-encode.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/abi-encode.yml diff --git a/.github/workflows/abi-encode.yml b/.github/workflows/abi-encode.yml new file mode 100644 index 000000000..2e6930667 --- /dev/null +++ b/.github/workflows/abi-encode.yml @@ -0,0 +1,25 @@ +name: ABI Encode Constructor Arguments + +on: + push: + branches: + - main + +jobs: + abi_encode: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: 14 + + - name: Install dependencies + run: npm install + + - name: ABI Encode + run: npm run abi-encode From 8cb314731c16be13ffcc74c6c16d32630544264a Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:50:01 -0400 Subject: [PATCH 06/19] Delete npm-gulp.yml --- .github/workflows/npm-gulp.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/npm-gulp.yml diff --git a/.github/workflows/npm-gulp.yml b/.github/workflows/npm-gulp.yml deleted file mode 100644 index 572444eab..000000000 --- a/.github/workflows/npm-gulp.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: NodeJS with Gulp - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.x, 16.x, 18.x] - - steps: - - uses: actions/checkout@v3 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - - name: Build - run: | - npm install - gulp From ca354f3cd6af61ad942040435906d72f23ff0bd2 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:55:14 -0400 Subject: [PATCH 07/19] Update abi-encode.js --- scripts/abi-encode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/abi-encode.js b/scripts/abi-encode.js index 04f344c6b..4d8be8284 100644 --- a/scripts/abi-encode.js +++ b/scripts/abi-encode.js @@ -2,7 +2,7 @@ const Web3 = require('web3'); // Replace the following values with your contract's constructor arguments const constructorArgs = [ - 'c4988f9629a4f68fe642f3f9c2407c6b4d723a38' + '000000000000000000000000c4988f9629a4f68fe642f3f9c2407c6b4d723a38' ]; const web3 = new Web3(); From dfae5dd58f3f1d58c5fb6bb39ab1b48943a7400b Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:56:55 -0400 Subject: [PATCH 08/19] Create npm-install --- .github/workflows/npm-install | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/workflows/npm-install diff --git a/.github/workflows/npm-install b/.github/workflows/npm-install new file mode 100644 index 000000000..b0da2d02d --- /dev/null +++ b/.github/workflows/npm-install @@ -0,0 +1,3 @@ +"scripts": { + "abi-encode": "node abi-encode.js" +} From b918e986b9eb13690fe2b6a8bc8262bf1de540ac Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:04:10 -0400 Subject: [PATCH 09/19] Delete abi-encode.yml --- .github/workflows/abi-encode.yml | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 .github/workflows/abi-encode.yml diff --git a/.github/workflows/abi-encode.yml b/.github/workflows/abi-encode.yml deleted file mode 100644 index 2e6930667..000000000 --- a/.github/workflows/abi-encode.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: ABI Encode Constructor Arguments - -on: - push: - branches: - - main - -jobs: - abi_encode: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up Node.js - uses: actions/setup-node@v2 - with: - node-version: 14 - - - name: Install dependencies - run: npm install - - - name: ABI Encode - run: npm run abi-encode From e70ed52f3888601ff9306cecbbd1d09e8c15732c Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:04:18 -0400 Subject: [PATCH 10/19] Delete npm-install --- .github/workflows/npm-install | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .github/workflows/npm-install diff --git a/.github/workflows/npm-install b/.github/workflows/npm-install deleted file mode 100644 index b0da2d02d..000000000 --- a/.github/workflows/npm-install +++ /dev/null @@ -1,3 +0,0 @@ -"scripts": { - "abi-encode": "node abi-encode.js" -} From eb30ae0003c5865852960fa675a6981ecba7a483 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:04:26 -0400 Subject: [PATCH 11/19] Delete npm-publish.yml --- .github/workflows/npm-publish.yml | 33 ------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/npm-publish.yml diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml deleted file mode 100644 index 6cdebafb6..000000000 --- a/.github/workflows/npm-publish.yml +++ /dev/null @@ -1,33 +0,0 @@ -# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created -# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages - -name: Node.js Package - -on: - release: - types: [created] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 16 - - run: npm ci - - run: npm test - - publish-npm: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 16 - registry-url: https://registry.npmjs.org/ - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} From 8d41e5f3a1a950602005e0693cb522bbbb55d403 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:04:39 -0400 Subject: [PATCH 12/19] Delete abi-encode.js --- scripts/abi-encode.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 scripts/abi-encode.js diff --git a/scripts/abi-encode.js b/scripts/abi-encode.js deleted file mode 100644 index 4d8be8284..000000000 --- a/scripts/abi-encode.js +++ /dev/null @@ -1,11 +0,0 @@ -const Web3 = require('web3'); - -// Replace the following values with your contract's constructor arguments -const constructorArgs = [ - '000000000000000000000000c4988f9629a4f68fe642f3f9c2407c6b4d723a38' -]; - -const web3 = new Web3(); -const encodedArgs = web3.eth.abi.encodeParameters(['address'], constructorArgs); - -console.log(`ABI-encoded constructor arguments: ${encodedArgs}`); From 8813553ea338301550c27d44d378c418e9511282 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:09:52 -0400 Subject: [PATCH 13/19] Create npm-publish.yml --- .github/workflows/npm-publish.yml | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/npm-publish.yml diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 000000000..6cdebafb6 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,33 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages + +name: Node.js Package + +on: + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + - run: npm ci + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.npm_token}} From 5174142277bf6384a2b0accc9d7381ad4cdc8d0b Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:14:40 -0400 Subject: [PATCH 14/19] Create abi-encode.yml --- .github/workflows/abi-encode.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/abi-encode.yml diff --git a/.github/workflows/abi-encode.yml b/.github/workflows/abi-encode.yml new file mode 100644 index 000000000..2e6930667 --- /dev/null +++ b/.github/workflows/abi-encode.yml @@ -0,0 +1,25 @@ +name: ABI Encode Constructor Arguments + +on: + push: + branches: + - main + +jobs: + abi_encode: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: 14 + + - name: Install dependencies + run: npm install + + - name: ABI Encode + run: npm run abi-encode From 4458f3a3fb50b4a5a7e3eecce5b30198be420d3c Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:36:58 -0400 Subject: [PATCH 15/19] Add files via upload Dollar Token Smart Contract --- contracts/Dollar.sol | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 contracts/Dollar.sol diff --git a/contracts/Dollar.sol b/contracts/Dollar.sol new file mode 100644 index 000000000..3f429286b --- /dev/null +++ b/contracts/Dollar.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/token/ERC20/ERC20.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/access/Ownable.sol"; + +contract DollarToken is ERC20, Ownable { + bool private _contractCreated; + address private _tokenFactory; + + modifier onlyTokenFactory() { + require(msg.sender == _tokenFactory, "Only the token factory can create instances of this contract"); + _; + } + + constructor(address tokenFactory) ERC20("Dollar", "$") { + require(!_contractCreated, "Contract already created"); + _contractCreated = true; + _tokenFactory = tokenFactory; + + uint256 initialSupply = 32674174016000000000000 * (10**6); // 32,674,174,016 tokens with 6 decimals + _mint(msg.sender, initialSupply); + } + + function additionalMint(uint256 amount) public onlyOwner { + _mint(msg.sender, amount); + } + + function burn(uint256 amount) public { + _burn(msg.sender, amount); + } +} + \ No newline at end of file From d48ef6c7b724a01d5ee499087b858b9148d116b5 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:37:50 -0400 Subject: [PATCH 16/19] Add files via upload Token Factory Smart Contract --- Dollar.sol | 33 +++++++++++++++++++++++++++++++++ TokenFactory.sol | 21 +++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 Dollar.sol create mode 100644 TokenFactory.sol diff --git a/Dollar.sol b/Dollar.sol new file mode 100644 index 000000000..3f429286b --- /dev/null +++ b/Dollar.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/token/ERC20/ERC20.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/access/Ownable.sol"; + +contract DollarToken is ERC20, Ownable { + bool private _contractCreated; + address private _tokenFactory; + + modifier onlyTokenFactory() { + require(msg.sender == _tokenFactory, "Only the token factory can create instances of this contract"); + _; + } + + constructor(address tokenFactory) ERC20("Dollar", "$") { + require(!_contractCreated, "Contract already created"); + _contractCreated = true; + _tokenFactory = tokenFactory; + + uint256 initialSupply = 32674174016000000000000 * (10**6); // 32,674,174,016 tokens with 6 decimals + _mint(msg.sender, initialSupply); + } + + function additionalMint(uint256 amount) public onlyOwner { + _mint(msg.sender, amount); + } + + function burn(uint256 amount) public { + _burn(msg.sender, amount); + } +} + \ No newline at end of file diff --git a/TokenFactory.sol b/TokenFactory.sol new file mode 100644 index 000000000..211e3c9fd --- /dev/null +++ b/TokenFactory.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/token/ERC20/ERC20.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/access/Ownable.sol"; + +contract DollarTokenFactory is Ownable { + event TokenCreated(address indexed tokenAddress); + + function createToken(string memory name, string memory symbol, uint256 initialSupply) external onlyOwner { + DollarToken token = new DollarToken(name, symbol, initialSupply); + emit TokenCreated(address(token)); + } +} + +contract DollarToken is ERC20 { + constructor(string memory name, string memory symbol, uint256 initialSupply) ERC20(name, symbol) { + _mint(msg.sender, initialSupply); + } +} + From a382ff5ff2d0bb7a78294cadfcdd7dcfad9bd3b3 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:38:39 -0400 Subject: [PATCH 17/19] Add files via upload --- contracts/TokenFactory.sol | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 contracts/TokenFactory.sol diff --git a/contracts/TokenFactory.sol b/contracts/TokenFactory.sol new file mode 100644 index 000000000..211e3c9fd --- /dev/null +++ b/contracts/TokenFactory.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/token/ERC20/ERC20.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.0/contracts/access/Ownable.sol"; + +contract DollarTokenFactory is Ownable { + event TokenCreated(address indexed tokenAddress); + + function createToken(string memory name, string memory symbol, uint256 initialSupply) external onlyOwner { + DollarToken token = new DollarToken(name, symbol, initialSupply); + emit TokenCreated(address(token)); + } +} + +contract DollarToken is ERC20 { + constructor(string memory name, string memory symbol, uint256 initialSupply) ERC20(name, symbol) { + _mint(msg.sender, initialSupply); + } +} + From 7d7bfe2d6a0ca3ac211b6f1f0c71934ff6099b55 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:42:38 -0400 Subject: [PATCH 18/19] Update abi-encode.yml --- .github/workflows/abi-encode.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/abi-encode.yml b/.github/workflows/abi-encode.yml index 2e6930667..a65dddbb6 100644 --- a/.github/workflows/abi-encode.yml +++ b/.github/workflows/abi-encode.yml @@ -1,14 +1,12 @@ -name: ABI Encode Constructor Arguments - +name: ABI Encode on: push: branches: - - main + - master # Replace with your branch name jobs: - abi_encode: + abi-encode: runs-on: ubuntu-latest - steps: - name: Checkout repository uses: actions/checkout@v2 @@ -22,4 +20,7 @@ jobs: run: npm install - name: ABI Encode - run: npm run abi-encode + uses: blocklytics/abi-encoder-action@1.1.1 + with: + contractPath: ./contracts/Dollar.sol # Replace with your contract path + arguments: '000000000000000000000000123456789abcdefABCDEF123456789ABCDEF123' # Replace with your constructor arguments From b3fea4c2487ace10731a3892f33565b4f92851d1 Mon Sep 17 00:00:00 2001 From: DollarToken1792 <137087030+DollarToken1792@users.noreply.github.com> Date: Mon, 19 Jun 2023 19:49:24 -0400 Subject: [PATCH 19/19] Add files via upload --- contracts/ERC20.sol | 356 ++++++++++++++++++++++++++++++++++++++++++ contracts/Ownable.sol | 76 +++++++++ 2 files changed, 432 insertions(+) create mode 100644 contracts/ERC20.sol create mode 100644 contracts/Ownable.sol diff --git a/contracts/ERC20.sol b/contracts/ERC20.sol new file mode 100644 index 000000000..a8c60e595 --- /dev/null +++ b/contracts/ERC20.sol @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.0 (token/ERC20/ERC20.sol) + +pragma solidity ^0.8.0; + +import "./IERC20.sol"; +import "./extensions/IERC20Metadata.sol"; +import "../../utils/Context.sol"; + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * For a generic mechanism see {ERC20PresetMinterPauser}. + * + * TIP: For a detailed writeup see our guide + * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC20 + * applications. + * + * Additionally, an {Approval} event is emitted on calls to {transferFrom}. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + * + * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} + * functions have been added to mitigate the well-known issues around setting + * allowances. See {IERC20-approve}. + */ +contract ERC20 is Context, IERC20, IERC20Metadata { + mapping(address => uint256) private _balances; + + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * The default value of {decimals} is 18. To select a different value for + * {decimals} you should overload it. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the value {ERC20} uses, unless this function is + * overridden; + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual override returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view virtual override returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(_msgSender(), recipient, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { + _approve(_msgSender(), spender, amount); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * Requirements: + * + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + * - the caller must have allowance for ``sender``'s tokens of at least + * `amount`. + */ + function transferFrom( + address sender, + address recipient, + uint256 amount + ) public virtual override returns (bool) { + _transfer(sender, recipient, amount); + + uint256 currentAllowance = _allowances[sender][_msgSender()]; + require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); + unchecked { + _approve(sender, _msgSender(), currentAllowance - amount); + } + + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + uint256 currentAllowance = _allowances[_msgSender()][spender]; + require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); + unchecked { + _approve(_msgSender(), spender, currentAllowance - subtractedValue); + } + + return true; + } + + /** + * @dev Moves `amount` of tokens from `sender` to `recipient`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + */ + function _transfer( + address sender, + address recipient, + uint256 amount + ) internal virtual { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); + + _beforeTokenTransfer(sender, recipient, amount); + + uint256 senderBalance = _balances[sender]; + require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); + unchecked { + _balances[sender] = senderBalance - amount; + } + _balances[recipient] += amount; + + emit Transfer(sender, recipient, amount); + + _afterTokenTransfer(sender, recipient, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _beforeTokenTransfer(address(0), account, amount); + + _totalSupply += amount; + _balances[account] += amount; + emit Transfer(address(0), account, amount); + + _afterTokenTransfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _beforeTokenTransfer(account, address(0), amount); + + uint256 accountBalance = _balances[account]; + require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); + unchecked { + _balances[account] = accountBalance - amount; + } + _totalSupply -= amount; + + emit Transfer(account, address(0), amount); + + _afterTokenTransfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve( + address owner, + address spender, + uint256 amount + ) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} + + /** + * @dev Hook that is called after any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * has been transferred to `to`. + * - when `from` is zero, `amount` tokens have been minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens have been burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} +} diff --git a/contracts/Ownable.sol b/contracts/Ownable.sol new file mode 100644 index 000000000..04f3f14d5 --- /dev/null +++ b/contracts/Ownable.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol) + +pragma solidity ^0.8.0; + +import "../utils/Context.sol"; + +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * By default, the owner account will be the one that deploys the contract. This + * can later be changed with {transferOwnership}. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +abstract contract Ownable is Context { + address private _owner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + /** + * @dev Initializes the contract setting the deployer as the initial owner. + */ + constructor() { + _transferOwnership(_msgSender()); + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view virtual returns (address) { + return _owner; + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(owner() == _msgSender(), "Ownable: caller is not the owner"); + _; + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions anymore. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby removing any functionality that is only available to the owner. + */ + function renounceOwnership() public virtual onlyOwner { + _transferOwnership(address(0)); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public virtual onlyOwner { + require(newOwner != address(0), "Ownable: new owner is the zero address"); + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Internal function without access restriction. + */ + function _transferOwnership(address newOwner) internal virtual { + address oldOwner = _owner; + _owner = newOwner; + emit OwnershipTransferred(oldOwner, newOwner); + } +}