Created
July 19, 2021 05:24
-
-
Save yograterol/4c7f03e7fc411e279c52b4be1e033b79 to your computer and use it in GitHub Desktop.
Dragonary Smart Contracts to Audit
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: MIT | |
pragma solidity ^0.7.0; | |
import "@openzeppelin/contracts/access/AccessControl.sol"; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol"; | |
import "@openzeppelin/contracts/utils/Context.sol"; | |
import "@openzeppelin/contracts/drafts/ERC20Permit.sol"; | |
import "./ERC20Capped.sol"; | |
contract CoinaryToken is Context, AccessControl, ERC20Burnable, ERC20Capped, ERC20Permit { | |
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); | |
uint public constant MAX_DAILY_MINTING_AMOUNT = 2000000 ether; | |
uint private _daily_minting_amount = MAX_DAILY_MINTING_AMOUNT; | |
uint public nextMintingDate; | |
// Test values | |
address public constant TEAM_ADDRESS = 0x98Ea123e74d6aa89988efe856866bB0E27B61768; | |
address public constant INVESTOR_ADDRESS = 0x1F2d3c15cb55016dCbf4909065Dd501949a4e1fe; | |
address public constant AIRDROP_ADDRESS = 0xDB84042f12747369a4A41157408937dC29629Fd3; | |
// Production values | |
// address public constant TEAM_ADDRESS = 0x0; | |
// address public constant INVESTOR_ADDRESS = 0x0; | |
// address public constant AIRDROP_ADDRESS = 0x0; | |
/** | |
* @dev Grants `DEFAULT_ADMIN_ROLE` and `MINTER_ROLE` to the | |
* account that deploys the contract. | |
* | |
* See {ERC20-constructor}. | |
*/ | |
constructor( | |
string memory name, | |
string memory symbol, | |
uint256 cap | |
) ERC20(name, symbol) ERC20Capped(cap) ERC20Permit(name) { | |
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); | |
_setupRole(MINTER_ROLE, _msgSender()); | |
// Mint tokens for team | |
_mint(TEAM_ADDRESS, 50000000 ether); | |
// Mint tokens for investors | |
_mint(INVESTOR_ADDRESS, 160000000 ether); | |
// Mint tokens for Airdrop | |
_mint(AIRDROP_ADDRESS, 41000000 ether); | |
nextMintingDate = block.timestamp + 1 days; | |
} | |
/** | |
* @dev Creates `amount` new tokens for `to`. | |
* | |
* See {ERC20-_mint}. | |
* | |
* Requirements: | |
* | |
* - the caller must have the `MINTER_ROLE`. | |
* - the amount to mint must be less or equal to MAX_DAILY_MINTING_AMOUNT | |
*/ | |
function mint(address to, uint256 amount) public virtual { | |
require( | |
hasRole(MINTER_ROLE, _msgSender()), | |
"CoinaryToken: must have minter role to mint" | |
); | |
require(amount <= MAX_DAILY_MINTING_AMOUNT, "CoinaryToken: The amount is highest than the MAX_DAILY_MINTING_AMOUNT"); | |
require(amount <= _daily_minting_amount, "CoinaryToken: The amount is highest than the daily_minting_amount"); | |
require(block.timestamp >= nextMintingDate, "CoinaryToken: You must wait 24 hours until the next minting"); | |
_mint(to, amount); | |
nextMintingDate = block.timestamp + 1 days; | |
} | |
/** | |
* @dev Change the daily minting amount. | |
* | |
* Requirements: | |
* | |
* - the caller must have the `MINTER_ROLE`. | |
* - the amount to mint must be less or equal to MAX_DAILY_MINTING_AMOUNT | |
*/ | |
function changeDailyMintingAmount(uint256 amount) public virtual { | |
require( | |
hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), | |
"CoinaryToken: must have admin role to change the daily minting amount." | |
); | |
require(amount <= MAX_DAILY_MINTING_AMOUNT, "CoinaryToken: The amount is highest than the MAX_DAILY_MINTING_AMOUNT"); | |
_daily_minting_amount = amount; | |
} | |
function dailyMintingAmount() public view virtual returns (uint) { | |
return _daily_minting_amount; | |
} | |
function _beforeTokenTransfer( | |
address from, | |
address to, | |
uint256 amount | |
) internal virtual override(ERC20, ERC20Capped) { | |
super._beforeTokenTransfer(from, 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: MIT | |
pragma solidity ^0.7.0; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import "@openzeppelin/contracts/utils/Counters.sol"; | |
import "@openzeppelin/contracts/access/AccessControl.sol"; | |
import "@openzeppelin/contracts/utils/Context.sol"; | |
contract DragonsERC721 is Context, AccessControl, ERC721 { | |
using Counters for Counters.Counter; | |
Counters.Counter private _tokenIdTracker; | |
mapping(uint256 => bool) private _burnedDragon; | |
// Events | |
event NewDragon(address player, uint256 dragonId); | |
event Burn(address indexed _called, uint256 _dragonId); | |
event Restore(address indexed _called, uint256 _dragonId, bool burnStatus); | |
// Access Control Roles | |
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); | |
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); | |
constructor() ERC721("Dragonary Dragons", "DRAGON") { | |
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); | |
_setupRole(MINTER_ROLE, _msgSender()); | |
_setupRole(BURNER_ROLE, _msgSender()); | |
_setBaseURI("https://items.dragonary.com/dragons/"); | |
} | |
function mintDragon(address player) public returns (uint256) { | |
require( | |
hasRole(MINTER_ROLE, _msgSender()), | |
"DragonsERC721: must have minter role to mint" | |
); | |
_tokenIdTracker.increment(); | |
uint256 newDragon = _tokenIdTracker.current(); | |
_mint(player, newDragon); | |
emit NewDragon(player, newDragon); | |
return newDragon; | |
} | |
// Soft burn to avoid delete completely the dragon | |
function softBurnDragon(uint256 dragonId) public returns (bool) { | |
require( | |
hasRole(BURNER_ROLE, _msgSender()), | |
"DragonsERC721: must have burner role" | |
); | |
require(_exists(dragonId), "DragonsERC721: Dragon didn't exist"); | |
_burnedDragon[dragonId] = true; | |
emit Burn(_msgSender(), dragonId); | |
return true; | |
} | |
function isBurned(uint256 dragonId) public view virtual returns (bool) { | |
return _burnedDragon[dragonId]; | |
} | |
/* | |
* Use only if some issues with the server game happens | |
* ONLY ADMIN CAN CALL THIS FUNCTION | |
*/ | |
function restoreDragon(uint256 dragonId, bool burnStatus) public returns (bool) { | |
require( | |
hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), | |
"DragonsERC721: must have admin role" | |
); | |
require(_exists(dragonId), "DragonsERC721: Dragon didn't exist"); | |
_burnedDragon[dragonId] = burnStatus; | |
emit Restore(_msgSender(), dragonId, burnStatus); | |
return true; | |
} | |
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721) { | |
require(_burnedDragon[tokenId] == false, "DragonsERC721: Dragon is burned"); | |
} | |
} |
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: MIT | |
pragma solidity ^0.7.0; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
/** | |
* @dev Extension of {ERC20} that adds a cap to the supply of tokens. | |
*/ | |
abstract contract ERC20Capped is ERC20 { | |
using SafeMath for uint256; | |
uint256 private _cap; | |
/** | |
* @dev Sets the value of the `cap`. This value is immutable, it can only be | |
* set once during construction. | |
*/ | |
constructor (uint256 cap_) { | |
require(cap_ > 0, "ERC20Capped: cap is 0"); | |
_cap = cap_; | |
} | |
/** | |
* @dev Returns the cap on the token's total supply. | |
*/ | |
function cap() public view virtual returns (uint256) { | |
return _cap; | |
} | |
/** | |
* @dev See {ERC20-_beforeTokenTransfer}. | |
* | |
* Requirements: | |
* | |
* - minted tokens must not cause the total supply to go over the cap. | |
*/ | |
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { | |
super._beforeTokenTransfer(from, to, amount); | |
if (from == address(0)) { // When minting tokens | |
require(totalSupply().add(amount) <= cap(), "ERC20Capped: cap exceeded"); | |
} | |
if (to == address(0)) { // When burning tokens | |
_cap = _cap.sub(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: MIT | |
pragma solidity ^0.7.0; | |
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; | |
import "@openzeppelin/contracts/utils/Context.sol"; | |
import "@openzeppelin/contracts/math/SafeMath.sol"; | |
/** | |
* @title ERC20VestingWallet | |
* @dev This contract handles the vesting of ERC20 tokens for a given beneficiary. Custody of multiple tokens can be | |
* given to this contract, which will release the token to the beneficiary following a given vesting schedule. The | |
* vesting schedule is customizable through the {vestedAmount} function. | |
* | |
* Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning. | |
* Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly) | |
* be immediately releasable. | |
*/ | |
contract ERC20VestingWallet is Context { | |
using SafeMath for uint256; | |
event TokensReleased(address token, uint256 amount); | |
mapping(address => uint256) private _released; | |
address private immutable _beneficiary; | |
uint256 private immutable _start; | |
uint256 private immutable _duration; | |
modifier onlyBeneficiary() { | |
require(beneficiary() == _msgSender(), "ERC20VestingWallet: access restricted to beneficiary"); | |
_; | |
} | |
/** | |
* @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet. | |
*/ | |
constructor( | |
address beneficiaryAddress | |
) { | |
require(beneficiaryAddress != address(0), "ERC20VestingWallet: beneficiary is zero address"); | |
_beneficiary = beneficiaryAddress; | |
_start = block.timestamp; | |
// Mainnet Value | |
// _duration = 10 years; | |
// Test Value | |
_duration = 1 days; | |
} | |
/** | |
* @dev Getter for the beneficiary address. | |
*/ | |
function beneficiary() public view virtual returns (address) { | |
return _beneficiary; | |
} | |
/** | |
* @dev Getter for the start timestamp. | |
*/ | |
function start() public view virtual returns (uint256) { | |
return _start; | |
} | |
/** | |
* @dev Getter for the vesting duration. | |
*/ | |
function duration() public view virtual returns (uint256) { | |
return _duration; | |
} | |
/** | |
* @dev Amont of token already released | |
*/ | |
function released(address token) public view returns (uint256) { | |
return _released[token]; | |
} | |
/** | |
* @dev Release the tokens that have already vested. | |
* | |
* Emits a {TokensReleased} event. | |
*/ | |
function release(address token) public virtual { | |
uint256 releasable = vestedAmount(token, block.timestamp) - released(token); | |
_released[token] += releasable; | |
emit TokensReleased(token, releasable); | |
SafeERC20.safeTransfer(IERC20(token), beneficiary(), releasable); | |
} | |
/** | |
* @dev Calculates the amount that has already vested. Default implementation is a linear vesting curve. | |
*/ | |
function vestedAmount(address token, uint256 timestamp) public view virtual returns (uint256) { | |
if (timestamp < start()) { | |
return 0; | |
} else if (timestamp >= start().add(duration())) { | |
return _historicalBalance(token); | |
} else { | |
return _historicalBalance(token).mul(timestamp.sub(start())).div(duration()); | |
} | |
} | |
/** | |
* @dev Calculates the historical balance (current balance + already released balance). | |
*/ | |
function _historicalBalance(address token) internal view virtual returns (uint256) { | |
return IERC20(token).balanceOf(address(this)) + released(token); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment