-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
32,863 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
ALCHEMY_API_KEY= | ||
ROPSTEN_PRIVATE_KEY= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
node_modules | ||
.env | ||
|
||
#Hardhat files | ||
cache | ||
artifacts | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"overrides": [ | ||
{ | ||
"files": "*.sol", | ||
"options": { | ||
"printWidth": 120, | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": false, | ||
"bracketSpacing": false, | ||
"explicitTypes": "always", | ||
"semi": true | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
/* | ||
Requirements: | ||
- Must receive eth in exchange for an ERC20 token | ||
- There is a recipient address that receives all incoming eth. | ||
- Exchange rate is fixed. 1 eth = 1000 tokens | ||
- Minimum investment is 0.01 eth and maximum is 5 eth. | ||
- The ICO hardcap is 300 eth. | ||
- An admin decides when the ICO starts and ends. | ||
- The ICO ends when the hardcap is reached or end time is reached. | ||
- The token will be tradeable only after a specific time set by the admin | ||
*/ | ||
|
||
pragma solidity ^0.8.7; | ||
|
||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import "./Token.sol"; | ||
|
||
uint256 constant TOKENS_PER_ETH = 1000; | ||
uint256 constant HARDCAP = 10 ether; | ||
uint256 constant MIN_INVESTMENT = 0.01 ether; | ||
uint256 constant MAX_INVESTMENT = 5 ether; | ||
|
||
contract ICO is Ownable { | ||
address payable recipient; // address that will receive all invested eth | ||
uint256 totalRaised; // keep track of raised eth | ||
uint256 public startBlock; // block after which investment is allowed | ||
uint256 public endBlock; // block until which investment is allowed | ||
Token public token; // ERC20 token minted from this ICO | ||
|
||
event Invested(address indexed investor, uint256 etherValue, uint256 tokensReceived); | ||
|
||
constructor( | ||
address payable _recipient, | ||
uint256 _startBlock, | ||
uint256 _endBlock, | ||
uint256 _tradeableAfterBlock | ||
) { | ||
recipient = _recipient; | ||
startBlock = _startBlock; | ||
endBlock = _endBlock; | ||
token = new Token(_tradeableAfterBlock); | ||
} | ||
|
||
modifier notFinished() { | ||
require(block.number >= startBlock, "ICO not started yet"); | ||
require(block.number <= endBlock, "ICO already finished"); | ||
_; | ||
} | ||
|
||
function invest() public payable notFinished { | ||
require(msg.value >= MIN_INVESTMENT, "Minimum investment is 0.01 eth"); | ||
require(msg.value <= MAX_INVESTMENT, "Maximum investment is 5 eth"); | ||
|
||
// Ensure hardcap is not passed even with current investment | ||
totalRaised += msg.value; | ||
require(totalRaised <= HARDCAP, "Hardcap exceeded"); | ||
|
||
// Send eth to the contract's recipient | ||
recipient.transfer(msg.value); | ||
|
||
// Mint tokens for the investor | ||
uint256 tokens = msg.value * TOKENS_PER_ETH; | ||
token.mint(msg.sender, tokens); | ||
|
||
emit Invested(msg.sender, msg.value, tokens); | ||
} | ||
|
||
function setBlocks(uint256 _startBlock, uint256 _endBlock) public onlyOwner { | ||
startBlock = _startBlock; | ||
endBlock = _endBlock; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
// ICO Token | ||
|
||
pragma solidity ^0.8.7; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
|
||
contract Token is ERC20('Terra Vision', 'TVI'), Ownable { | ||
uint tradeableAfterBlock; | ||
|
||
constructor(uint _tradeableAfterBlock){ | ||
tradeableAfterBlock = _tradeableAfterBlock; | ||
} | ||
|
||
function mint(address account, uint amount) public onlyOwner { | ||
_mint(account, amount); | ||
} | ||
|
||
function _transfer(address sender, address recipient, uint amount) internal override { | ||
require(block.number >= tradeableAfterBlock, "Token is not tradeable yet"); | ||
ERC20._transfer(sender, recipient, amount); | ||
} | ||
|
||
function setTradeableAfterBlock(uint _tradeableAfterBlock) public onlyOwner { | ||
tradeableAfterBlock = _tradeableAfterBlock; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { task } from "hardhat/config"; | ||
import "@nomiclabs/hardhat-waffle"; | ||
import "hardhat-gas-reporter" | ||
import "hardhat-tracer" | ||
import "@atixlabs/hardhat-time-n-mine" | ||
import "@atixlabs/hardhat-time-n-mine/dist/src/type-extensions"; | ||
|
||
import dotenv from 'dotenv' | ||
dotenv.config() | ||
|
||
// This is a sample Hardhat task. To learn how to create your own go to | ||
// https://hardhat.org/guides/create-task.html | ||
task("accounts", "Prints the list of accounts", async (args, hre) => { | ||
const accounts = await hre.ethers.getSigners(); | ||
|
||
for (const account of accounts) { | ||
console.log(await account.address); | ||
} | ||
}); | ||
|
||
// You need to export an object to set up your config | ||
// Go to https://hardhat.org/config/ to learn more | ||
|
||
export default { | ||
solidity: { | ||
version: '0.8.7', | ||
settings: { | ||
outputSelection: { | ||
"*": { | ||
"*": ["storageLayout"], | ||
}, | ||
}, | ||
} | ||
}, | ||
networks: { | ||
ropsten: { | ||
url: `https://eth-ropsten.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}`, | ||
accounts: [`0x${process.env.ROPSTEN_PRIVATE_KEY}`], | ||
}, | ||
}, | ||
}; |
Oops, something went wrong.