Skip to content

Instantly share code, notes, and snippets.

@C2OO13
Created March 19, 2021 13:01
Show Gist options
  • Save C2OO13/afcaaf01a52885a74c57372eb2625f44 to your computer and use it in GitHub Desktop.
Save C2OO13/afcaaf01a52885a74c57372eb2625f44 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.2+commit.661d1103.js&optimize=true&runs=200&gist=
REMIX EXAMPLE PROJECT
Remix example project is present when Remix loads very first time or there are no files existing in the File Explorer.
It contains 3 directories:
1. 'contracts': Holds three contracts with different complexity level, denoted with number prefix in file name.
2. 'scripts': Holds two scripts to deploy a contract. It is explained below.
3. 'tests': Contains one test file for 'Ballot' contract with unit tests in Solidity.
SCRIPTS
The 'scripts' folder contains example async/await scripts for deploying the 'Storage' contract.
For the deployment of any other contract, 'contractName' and 'constructorArgs' should be updated (along with other code if required).
Scripts have full access to the web3.js and ethers.js libraries.
To run a script, right click on file name in the file explorer and click 'Run'. Remember, Solidity file must already be compiled.
Output from script will appear in remix terminal.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
contract Campaign{
struct Request{
string desc;
uint value;
address payable recipient;
bool complete;
mapping(address => bool) approvals;
uint cntApprovals;
}
address public manager;
uint public minContribution;
mapping(uint => Request) public requests;
mapping(address => bool) public approvers;
uint public cntRequests = 0;
uint public cntApprovers = 0;
constructor(uint amt,address creator){
manager=creator;
minContribution=amt;
}
modifier requireManager(){
require(msg.sender==manager,"Only manager is allowed to do this!");
_;
}
function setMinContribution(uint amt) public requireManager{
minContribution=amt;
}
function contribute() public payable{
require(msg.value>=minContribution,"You must contribute amount >= Minimum Contribution specified bu manager.");
approvers[msg.sender]=true;
cntApprovers++;
}
function makeRequest(string memory desc,uint val,address payable recipient) public requireManager{
Request storage newReq = requests[cntRequests++];
newReq.desc = desc;
newReq.value = val;
newReq.recipient = recipient;
newReq.complete=false;
newReq.cntApprovals=0;
}
function approveRequest(uint num) public {
Request storage req = requests[num];
require(approvers[msg.sender],"You must be a contributer to approve Request!!");
require(!req.approvals[msg.sender],"You can only vote once for a Request!");
req.cntApprovals++;
req.approvals[msg.sender]=true;
}
function finalizeRequest(uint num) public requireManager{
Request storage req = requests[num];
require(!req.complete,"Request is already completed!");
require(req.cntApprovals >= (cntApprovers/2),"You don't have enough votes to go on with this Request!");
req.complete = true;
payable(req.recipient).transfer(req.value);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import './Campaign.sol';
contract CampaignFactory{
address[] private deployedContracts;
Campaign private camp;
function createCampaign(uint amt) public{
camp = new Campaign(amt, msg.sender);
deployedContracts.push(address(camp));
}
function getDeployedContracts() public view returns(address[] memory){
return deployedContracts;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
interface EIP20Interface {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "./EIP20Interface.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is EIP20Interface {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
contract Inbox{
string public message;
constructor(string memory initialMessage){
message = initialMessage;
}
function setMessage (string memory newMessage) public {
message = newMessage;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
contract Lottery{
address public manager;
address payable[] public players;
constructor(){
manager=msg.sender;
}
modifier restricted(){
require(msg.sender == manager,"Only manager can start this process");
_;
}
function enter() public payable{
require(msg.value >= 0.01 ether,"0.01 ether is minimum amount to register for a player in the lottery.");
players.push(msg.sender);
}
function psuedoRandomNumberGenerator() private view returns (uint){
return uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players, manager)));
}
function pickWinner() public restricted{
require(players.length > 0, "Not enough players to run lottery!");
uint psuedoRandomNumber = psuedoRandomNumberGenerator();
uint countPlayers = players.length;
uint playerWon = (psuedoRandomNumber)%(countPlayers);
players[playerWon].transfer(address(this).balance);
players = new address payable[](0);
}
function getPlayers() public view returns (address payable[] memory){
return players;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "./NewERC20Token.sol";
import "./Ownable.sol";
contract MainContract is Ownable{
struct Agreement{
address payable investor;
address payable company;
uint256 moneyRequired;
uint256 tokensRequired;
address token;
uint8 status;//0=pending 1=accepted 2=completed 3=rejected
}
address payable public manager;
address[] private deployedTokens;
mapping(address => address) private addressToken;
mapping(address => uint256) private walletMoney;
mapping(address => mapping(address => uint256)) private walletTokens;
mapping(address => mapping(address => Agreement)) private agreements;
NewERC20Token private _token;
Agreement private _agr;
constructor(){
manager=payable(msg.sender);
}
modifier onlyManager(){
require(msg.sender == manager);
_;
}
fallback() external payable { revert(); }
receive() external payable { revert(); }
function createToken(string memory name_, string memory symbol_, uint256 totalSupply_) public{
_token = new NewERC20Token(name_,symbol_,totalSupply_, msg.sender);
walletTokens[msg.sender][address(_token)] = totalSupply_;
addressToken[msg.sender] = address(_token);
deployedTokens.push(address(_token));
}
function infoToken(address token) public view returns(string memory, string memory, uint256 ){
return (NewERC20Token(token).name(), NewERC20Token(token).symbol(), NewERC20Token(token).totalSupply());
}
function tokenBalance(address token, address sender) public view returns(uint256){
return NewERC20Token(token).balanceOf(sender);
}
function getContractAddress() public view returns(address){
return address(this);
}
function getAllDeployedTokens() public view returns(address[] memory){
return deployedTokens;
}
function getStartupToken(address deployer) public view returns(address){
return addressToken[deployer];
}
function getContractBalance() public view returns(uint256){
return address(this).balance;
}
function getDepositedBalance(address sender) public view returns(uint256){
return walletMoney[sender];
}
function getDepositedTokenBalance(address sender, address token) public view returns(uint256){
return walletTokens[sender][token];
}
function getAgreement(address investor, address company) public view returns(Agreement memory){
return agreements[investor][company];
}
// function getStartupAgreements(address startup) public view returns(Agreement[] memory ){
// return [];
// }
// function getInvestorAgreements(address investor) publc view returns(Agreement[] memory){
// }
function makeAgreement(address payable investor_, address payable company_, uint256 moneyRequired_, uint256 tokensRequired_, address token_) public {
require(msg.sender == company_, "Only startup can create an Agreement");
_agr = Agreement(investor_, company_, moneyRequired_, tokensRequired_, token_, 0);
agreements[investor_][company_] = _agr;
agreements[company_][investor_] = _agr;
}
function approveAgreement(address payable investor_, address payable company_) public{
_agr = agreements[investor_][company_];
require(msg.sender == _agr.investor);
_agr.status = 1;
}
function rejectAgreement(address payable investor_, address payable company_) public{
_agr = agreements[investor_][company_];
require(msg.sender == _agr.investor);
_agr.status = 3;
}
function completeAgreement(address payable investor_, address payable company_) public{
_agr = agreements[investor_][company_];
uint256 investorBal = getDepositedBalance(investor_);
uint256 companyBal = getDepositedTokenBalance(company_,address(_agr.token));
require(_agr.moneyRequired <= investorBal, "Investor money balance in contract is less than Agreement.");
require(_agr.tokensRequired <= companyBal, "Company token balance in contract is less than Agreement.");
_token = NewERC20Token(_agr.token);
payable(company_).transfer(_agr.moneyRequired);
NewERC20Token(_token).increaseAllowance(manager, investor_,_agr.tokensRequired);
NewERC20Token(_token).increaseAllowance(address(this), investor_,_agr.tokensRequired);
NewERC20Token(_token).increaseAllowance(address(this), manager,_agr.tokensRequired);
NewERC20Token(_token).increaseAllowance(manager, address(this),_agr.tokensRequired);
NewERC20Token(_token).transferFrom(manager, investor_, _agr.tokensRequired);
walletMoney[company_] = walletMoney[company_] + _agr.moneyRequired;
walletMoney[investor_] = walletMoney[investor_] - _agr.moneyRequired;
walletTokens[manager][address(_token)] = walletTokens[manager][address(_token)] - _agr.tokensRequired ;
walletTokens[investor_][address(_token)] = walletTokens[investor_][address(_token)] + _agr.tokensRequired ;
_agr.status = 2;
}
function depositMoney() public payable{
uint256 amount = msg.value;
walletMoney[msg.sender] = walletMoney[msg.sender] + amount;
}
function depositToken(address token_, uint256 amt_) public payable{
uint256 amt=tokenBalance(token_, msg.sender);
require(amt_<=amt,"You don't have enough token balance");
NewERC20Token(token_).increaseAllowance(msg.sender, address(this), amt_);
NewERC20Token(token_).increaseAllowance(msg.sender, manager, amt_);
NewERC20Token(token_).transferFrom(msg.sender, manager, amt_);
walletTokens[msg.sender][token_] = walletTokens[msg.sender][token_] - amt_ ;
walletTokens[manager][token_] = walletTokens[manager][token_] + amt_;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "./EIP20Interface.sol";
import "./IERC20Metadata.sol";
import "./Ownable.sol";
library SafeMath {
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract NewERC20Token is EIP20Interface, IERC20Metadata, Ownable {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
using SafeMath for uint256;
string private _name;
string private _symbol;
constructor (string memory name_, string memory symbol_, uint256 totalSupply_, address creator) {
_name = name_;
_symbol = symbol_;
_mint(creator, totalSupply_);
}
function transferAnyERC20Token(address tokenAddress, uint256 tokens) public onlyOwner returns (bool success) {
return EIP20Interface(tokenAddress).transfer(owner, tokens);
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
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");
_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 owner,address spender, uint256 addedValue) public virtual returns (bool) {
_approve(owner, spender, _allowances[owner][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");
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is 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");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(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:
*
* - `to` 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);
}
/**
* @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");
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
emit Transfer(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);
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
// this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
/**
* @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 to 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 { }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(this));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment