Created
November 5, 2022 06:28
-
-
Save ahmedali8/80ef53fbd4084cbe81e6d23a1bd584f6 to your computer and use it in GitHub Desktop.
Blockchain Genesis - Web3Disrupt Workshop
This file contains hidden or 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
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity ^0.8.9; | |
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
import { CoffeeMock } from "./Coffee_NFT.sol"; | |
contract Coffee { | |
struct Donate { | |
uint256 tokensDonated; | |
uint256 noOfDonations; | |
} | |
/*////////////////////////////////////////////////////////////// | |
STATE VARIABLES | |
//////////////////////////////////////////////////////////////*/ | |
IERC20 public token; | |
CoffeeMock public nft; | |
uint256 public priceOfCoffee; | |
address payable public owner; | |
mapping(address => Donate) private _donations; | |
/*////////////////////////////////////////////////////////////// | |
MODIFIERS | |
//////////////////////////////////////////////////////////////*/ | |
modifier onlyOwner() { | |
require(msg.sender == owner, "Revert: not an owner"); | |
_; | |
} | |
/*////////////////////////////////////////////////////////////// | |
EVENTS | |
//////////////////////////////////////////////////////////////*/ | |
event Withdrawal(uint256 tokenAmount, uint256 when); | |
event Deposit(uint256 amount, address sender); | |
event SetPriceOfCoffee(uint256 prevPriceOfCoffee, uint256 newPriceOfCoffee); | |
/*////////////////////////////////////////////////////////////// | |
CONSTRUCTOR | |
//////////////////////////////////////////////////////////////*/ | |
constructor( | |
uint256 _priceOfCoffee, | |
address _erc20, | |
address _erc721 | |
) { | |
priceOfCoffee = _priceOfCoffee; | |
token = IERC20(_erc20); | |
nft = CoffeeMock(_erc721); | |
owner = payable(msg.sender); | |
} | |
/*////////////////////////////////////////////////////////////// | |
EFFECT FUNCTIONS | |
//////////////////////////////////////////////////////////////*/ | |
/** | |
* @notice User can call this function to donate tokens equivalent | |
* to number of coffees to the owner. | |
* @dev User must have tokens to donate. | |
*/ | |
function donate(uint256 _numOfCoffees) external returns (bool) { | |
require(_numOfCoffees > 0, "Revert: bro donate 1 coffee atleast!"); | |
// loading state variable in memory for gas optimization | |
uint256 _priceOfCoffee = priceOfCoffee; | |
// multiply number of coffees to donate by price of coffee | |
// to get total donation | |
uint256 _noOfTokensToDonate = _priceOfCoffee * _numOfCoffees; | |
// save the token balance in a local variable | |
uint256 _tokenBalance = token.balanceOf(msg.sender); | |
// check if balance is greater then the donation amount | |
require(_tokenBalance > _noOfTokensToDonate, "Revert: bro you're broke as well!"); | |
// updating state | |
_donations[msg.sender].tokensDonated += _noOfTokensToDonate; | |
_donations[msg.sender].noOfDonations += 1; | |
// approval must be given from msg.sender to this contract address before | |
// transfers tokens from msg.sender to this contract | |
token.transferFrom(msg.sender, address(this), _noOfTokensToDonate); | |
for (uint256 i; i < _numOfCoffees; i++) { | |
// mint nft to msg.sender | |
nft.mintTo(msg.sender); | |
} | |
emit Deposit(_noOfTokensToDonate, msg.sender); | |
return true; | |
} | |
/** | |
* @notice Owner can withdraw tokens in the contract | |
* @dev Only callable by owner | |
*/ | |
function withdraw() external onlyOwner returns (bool) { | |
// save the token balance in a local variable | |
uint256 _balance = token.balanceOf(address(this)); | |
// check if tokens exist in this contract | |
require(_balance > 0, "Revert: No tokens in contract!"); | |
// transfer tokens in the contract to owner | |
token.transfer(owner, _balance); | |
emit Withdrawal(_balance, block.timestamp); | |
return true; | |
} | |
/** | |
* @notice Owner can set price of coffee | |
* @dev Only callable by owner | |
*/ | |
function setPriceOfCoffee(uint256 _priceOfCoffee) external onlyOwner { | |
emit SetPriceOfCoffee(priceOfCoffee, _priceOfCoffee); | |
priceOfCoffee = _priceOfCoffee; | |
} | |
/*////////////////////////////////////////////////////////////// | |
VIEW/PURE FUNCTIONS | |
//////////////////////////////////////////////////////////////*/ | |
/** | |
* @notice Returns info of `_user` | |
*/ | |
function getUserDetails(address _user) | |
external | |
view | |
returns ( | |
uint256, | |
uint256 | |
) | |
{ | |
return ( | |
_donations[_user].tokensDonated, | |
_donations[_user].noOfDonations | |
); | |
} | |
} |
This file contains hidden or 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
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity ^0.8.9; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
contract MyToken is ERC20 { | |
/*////////////////////////////////////////////////////////////// | |
CONSTRUCTOR | |
//////////////////////////////////////////////////////////////*/ | |
constructor( | |
string memory _name, | |
string memory _symbol | |
) | |
ERC20(_name, _symbol) | |
{ | |
// Mint 100 tokens to msg.sender | |
// Similar to how | |
// 1 dollar = 100 cents | |
// 1 token = 1 * (10 ** decimals) | |
uint8 _decimals = decimals(); | |
uint256 _typeCastedDecimals = uint256(_decimals); | |
_mint( | |
msg.sender, // account | |
10_000 * 10 ** _typeCastedDecimals // amount e.g. 10_000 x 10^18 | |
); | |
} | |
/*////////////////////////////////////////////////////////////// | |
EFFECT FUNCTIONS | |
//////////////////////////////////////////////////////////////*/ | |
/** | |
* @dev Mints a new MyToken tokens of amount `_amount` to address `_to` | |
* @notice This is not a production ready function as anyone can mint tokens | |
* Only for demo purposes | |
*/ | |
function mint(address _to, uint256 _amount) external { | |
_mint(_to, _amount); | |
} | |
} |
This file contains hidden or 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
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity ^0.8.9; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
contract CoffeeMock is ERC721 { | |
/*////////////////////////////////////////////////////////////// | |
STATE VARIABLES | |
//////////////////////////////////////////////////////////////*/ | |
// the current NFT ID tracker | |
// be default value is 0 | |
uint256 private _currentTokenId; | |
/*////////////////////////////////////////////////////////////// | |
CONSTRUCTOR | |
//////////////////////////////////////////////////////////////*/ | |
constructor( | |
string memory _name, | |
string memory _symbol | |
) ERC721(_name, _symbol) {} | |
/*////////////////////////////////////////////////////////////// | |
EFFECT FUNCTIONS | |
//////////////////////////////////////////////////////////////*/ | |
/** | |
* @dev Mints a new Coffee NFT to address `to` | |
* @notice This is not a production ready function as anyone can mint an nft | |
* Only for demo purposes | |
*/ | |
function mintTo(address _to) external { | |
// increment the token id | |
_currentTokenId++; | |
// get the incremented new token id | |
uint256 _id = _currentTokenId; | |
_safeMint(_to, _id); | |
} | |
/*////////////////////////////////////////////////////////////// | |
VIEW/PURE FUNCTIONS | |
//////////////////////////////////////////////////////////////*/ | |
/** | |
* @dev Returns the current token id | |
* @return uint256 for the current token ID | |
*/ | |
function currentTokenId() external view returns (uint256) { | |
return _currentTokenId; | |
} | |
/** | |
* @inheritdoc ERC721 | |
*/ | |
function tokenURI(uint256 tokenId) public view override returns (string memory) { | |
_requireMinted(tokenId); | |
// https://{cid}.ipfs.nftstorage.link/ | |
return "ipfs://bafkreidtzux4ez453colsi2vafe6ylskwze5ybbcogjdtnasp6erdamota"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment