文件 1 的 23:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 23:CIGAR.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "../interfaces/ICIGAR.sol";
contract CIGAR is ICIGAR, ERC20, Ownable {
uint256 public constant DAO_AMOUNT = 600000000000 ether;
uint256 public constant LIQUIDITY_AMOUNT = 150000000000 ether;
uint256 public constant TEAM_AMOUNT = 450000000000 ether;
uint256 public constant PUBLIC_SALE_AMOUNT = 300000000000 ether;
uint256 public constant STAKING_AMOUNT = 1500000000000 ether;
uint256 public constant TOTAL_AMOUNT = 3000000000000 ether;
uint256 public mintPrice = .00001 ether;
uint256 public maxMint = 10000;
uint256 public immutable timeStarted;
uint256 public teamValueMinted;
uint256 public publicSaleMinted;
uint256 public totalMinted;
bool public saleIsActive;
bool public areControllersLocked;
mapping(address => bool) public controllers;
constructor() ERC20("CIGAR", "CIGAR") {
timeStarted = block.timestamp;
}
function publicSaleMint(address to, uint256 amountInEther) external override payable {
require(saleIsActive, "Sale is not active");
uint256 amountInWei = amountInEther * 1 ether;
require(publicSaleMinted + amountInWei <= PUBLIC_SALE_AMOUNT, "The public sale cap has been reached");
require(amountInEther <= maxMint, "Amount requested is greater than max mint");
require(amountInEther * mintPrice == msg.value, "Given ether does not match price required");
_mint(to, amountInWei);
publicSaleMinted += amountInWei;
totalMinted += amountInWei;
}
function mint(address to, uint256 amount) external override {
require(controllers[msg.sender], "Only controllers are allowed to mint");
totalMinted += amount;
require(totalMinted <= TOTAL_AMOUNT, "Max CIGAR reached");
_mint(to, amount);
}
function reserveToDAO(address dao) external override onlyOwner {
totalMinted += DAO_AMOUNT;
_mint(dao, DAO_AMOUNT);
}
function reserveToLiquidity(address liquidityHandler) external override onlyOwner {
totalMinted += LIQUIDITY_AMOUNT;
_mint(liquidityHandler, LIQUIDITY_AMOUNT);
}
function reserveToTeam(address team) external override onlyOwner {
require(teamValueMinted < TEAM_AMOUNT, "Team amount has been fully vested");
uint256 quarter = 13 * (1 weeks);
uint256 quarterNum = (block.timestamp - timeStarted) / quarter;
require(quarterNum > 0, "A quarter has not passed");
uint256 quarterAmount = TEAM_AMOUNT / 4;
require(quarterNum * quarterAmount > teamValueMinted, "Quarter value already minted");
uint256 amountToMint = (quarterNum * quarterAmount) - teamValueMinted;
totalMinted += amountToMint;
teamValueMinted += amountToMint;
_mint(team, amountToMint);
}
function burn(address from, uint256 amount) external override {
require(controllers[msg.sender], "Only controllers are allowed to burn");
_burn(from, amount);
}
function addController(address controller) external override onlyOwner {
require(!areControllersLocked, 'Controllers have been locked! No more controllers allowed.');
controllers[controller] = true;
}
function removeController(address controller) external override onlyOwner {
require(!areControllersLocked, 'Controllers have been locked! No more changes allowed.');
controllers[controller] = false;
}
function flipSaleState() external override onlyOwner {
saleIsActive = !saleIsActive;
}
function setMintPrice(uint256 _mintPrice) external override onlyOwner {
mintPrice = _mintPrice;
}
function setMaxMint(uint256 _maxMint) external override onlyOwner {
maxMint = _maxMint;
}
function lockControllers() external override onlyOwner {
areControllersLocked = true;
}
function withdrawPublicSale() external override onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
}
文件 3 的 23:CigarClub.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./CIGAR.sol";
import "./TreasureChest.sol";
import "../Whales.sol";
import "../SecurityOrcas.sol";
import "../WealthyWhales.sol";
contract CigarClub is Ownable, IERC721Receiver {
struct WhaleOrcaStakeInfo {
uint16 orcaTokenId;
address owner;
uint256 stakeTimestamp;
}
struct WhaleWhaleStakeInfo {
uint16 whaleToken2Id;
address owner;
uint256 stakeTimestamp;
}
struct WealthyWhaleStakeInfo {
uint256 previousCigarVaultAmount;
uint256 stakeTimestamp;
address owner;
}
uint256 public constant DAILY_WHALE_RATE = 10000 ether;
uint256 public constant DAILY_WHALE_ORCA_RATE = DAILY_WHALE_RATE + (DAILY_WHALE_RATE / 4);
uint256 public constant DAILY_GOLD_WHALE_RATE = (2 * DAILY_WHALE_RATE) + (DAILY_WHALE_RATE / 2);
uint256 public constant DAILY_WHALE_YACHT_RATE = (3 * DAILY_WHALE_RATE);
uint256 public constant DAILY_GOLD_WHALE_ORCA_RATE = (3 * DAILY_WHALE_RATE) + (DAILY_WHALE_RATE / 8);
uint256 public constant DAILY_DOUBLE_GOLD_WHALE_RATE = 5 * DAILY_WHALE_RATE;
uint256 public constant DAILY_GOLD_WHALE_YACHT_RATE = (7 * DAILY_WHALE_RATE) + (DAILY_WHALE_RATE / 2);
uint256 public constant MIN_STAKING_TIME_WHALES = 2 days;
uint256 public constant MIN_STAKING_TIME_WEALTHY_WHALES = 6 days;
uint256 public constant WEALTHY_WHALE_TAX = 20;
uint256 public constant ZERO_WHALE = 10000;
CIGAR public cigar;
Whales public immutable whales;
SecurityOrcas public immutable securityOrcas;
WealthyWhales public immutable wealthyWhales;
mapping(uint256 => WhaleOrcaStakeInfo) public whaleOrcaClub;
mapping(uint256 => WhaleWhaleStakeInfo) public whaleWhaleClub;
mapping(uint256 => WealthyWhaleStakeInfo) public wealthyWhaleClub;
mapping(address => uint256) public whaleStaked;
uint256 public totalWhaleOrcasStaked;
uint256 public totalWhaleWhalesStaked;
uint256 public totalWealthyWhalesStaked;
uint256 public unclaimedWealthyWhaleVault;
uint256 public wealthyWhaleVault;
uint256 public immutable cigarStakingCap;
uint256 public cigarAwarded;
mapping(uint256 => bool) public isGoldWhale;
mapping(uint256 => bool) public isYacht;
mapping(uint256 => uint256) public whaleIdToRate;
mapping(uint256 => uint256) public orcaIdToRate;
event WhaleOrcaStaked(address owner, uint256 whaleId, uint256 orcaId, uint256 timestamp);
event WhaleWhaleStaked(address owner, uint256 whaleId, uint256 whale2Id, uint256 timestamp);
event WealthyWhaleStaked(address owner, uint256 tokenId, uint256 wealthyWhaleVault, uint256 timestamp);
event RewardsClaimedWhaleOrca(address owner, uint256 whaleId, uint256 orcaId, uint256 timestamp);
event RewardsClaimedWhaleWhale(address owner, uint256 whaleId, uint256 whale2Id, uint256 timestamp);
event RewardsClaimedWealthyWhale(address owner, uint256 tokenId, uint256 wealthyWhaleVault, uint256 timestamp);
event WhaleOrcaUnstaked(address owner, uint256 whaleId, uint256 orcaId, uint256 timestamp);
event WhaleWhaleUnstaked(address owner, uint256 whaleId, uint256 whale2Id, uint256 timestamp);
event WealthyWhaleUnstaked(address owner, uint256 tokenId, uint256 wealthyWhaleVault, uint256 timestamp);
constructor(address _whales, address _securityOrcas, address _cigar, address _wealthyWhales) {
whales = Whales(_whales);
securityOrcas = SecurityOrcas(_securityOrcas);
cigar = CIGAR(_cigar);
wealthyWhales = WealthyWhales(_wealthyWhales);
cigarStakingCap = cigar.STAKING_AMOUNT();
}
function stakeWhalesAndOrcasInCigarClub(uint256[] calldata whaleIds, uint256[] calldata orcaIds) external {
require(whaleIds.length == orcaIds.length, "Must stake an equal number of whales and orcas!");
for (uint i = 0; i < whaleIds.length; i++) {
require(whales.ownerOf(whaleIds[i]) == _msgSender(), "This is not your whale!");
require(securityOrcas.ownerOf(orcaIds[i]) == _msgSender(), "This is not your orca!");
whales.transferFrom(_msgSender(), address(this), whaleIds[i]);
securityOrcas.transferFrom(_msgSender(), address(this), orcaIds[i]);
_addWhaleAndOrcaToCigarClub(_msgSender(), whaleIds[i], orcaIds[i]);
}
totalWhaleOrcasStaked += whaleIds.length;
}
function stakeWhalesInCigarClub(uint256[] calldata whaleIds) external {
require(whaleIds.length > 1, "Must provide at least 2 whaleIds");
require(whaleIds.length % 2 == 0, "Must be even number of whales");
for (uint i = 0; i < whaleIds.length; i += 2) {
require(whales.ownerOf(whaleIds[i]) == _msgSender(), "This is not your whale!");
require(whales.ownerOf(whaleIds[i + 1]) == _msgSender(), "This is not your whale!");
whales.transferFrom(_msgSender(), address(this), whaleIds[i]);
whales.transferFrom(_msgSender(), address(this), whaleIds[i + 1]);
_addWhalesToCigarClub(_msgSender(), whaleIds[i], whaleIds[i + 1]);
}
totalWhaleWhalesStaked += whaleIds.length / 2;
}
function stakeWealthyWhalesInCigarClub(uint256[] calldata tokenIds) external {
for (uint i = 0; i < tokenIds.length; i++) {
require(wealthyWhales.ownerOf(tokenIds[i]) == _msgSender(), "This is not your token!");
wealthyWhales.transferFrom(_msgSender(), address(this), tokenIds[i]);
_addWealthyWhaleToCigarClub(_msgSender(), tokenIds[i]);
}
}
function claimWhalesAndOrcas(uint256[] calldata whaleIds, bool unstake) external {
uint256 reward;
for (uint i = 0; i < whaleIds.length; i++) {
reward += _claimWhaleOrcaAndGetReward(whaleIds[i], unstake);
}
if (reward == 0) return;
cigar.mint(_msgSender(), reward);
}
function claimWhales(uint256[] calldata whaleIds, bool unstake) external {
require(whaleIds.length > 0, "Must claim at least 1 whale");
uint256 reward;
for (uint i = 0; i < whaleIds.length; i++) {
reward += _claimWhalesAndGetReward(whaleIds[i], unstake);
}
if (reward == 0) return;
cigar.mint(_msgSender(), reward);
}
function claimWealthyWhales(uint256[] calldata tokenIds, bool unstake) external {
uint256 reward;
for (uint i = 0; i < tokenIds.length; i++) {
reward += _claimWealthyWhaleAndGetReward(tokenIds[i], unstake);
}
if (reward == 0) return;
cigar.mint(_msgSender(), reward);
}
function onERC721Received(address, address from, uint256 tokenId, bytes calldata)
external override returns (bytes4) {
require(msg.sender == address(securityOrcas) || msg.sender == address(whales),
"Only accepts whale and security orca tokens");
uint256 currentWhale = whaleStaked[from];
if (msg.sender == address(whales)) {
require(currentWhale == 0, "Must not have sent other unstaked whales");
if (tokenId == 0) {
whaleStaked[from] = ZERO_WHALE;
} else {
whaleStaked[from] = tokenId;
}
} else if (msg.sender == address(securityOrcas)) {
require(currentWhale != 0, "This address must have deposited a whale first!");
if (currentWhale == ZERO_WHALE) {
currentWhale = 0;
}
_addWhaleAndOrcaToCigarClub(from, currentWhale, tokenId);
whaleStaked[from] = 0;
totalWhaleOrcasStaked++;
}
return IERC721Receiver.onERC721Received.selector;
}
function retrieveLoneWhale() external {
uint256 whaleId = whaleStaked[_msgSender()];
require(whaleId != 0, "User must have sent an unstaked whale");
whaleStaked[_msgSender()] = 0;
whales.safeTransferFrom(address(this), _msgSender(), whaleId, "");
}
function setGoldWhales(uint256[] calldata goldWhaleIds) external onlyOwner {
for(uint256 i = 0; i < goldWhaleIds.length; i++) {
isGoldWhale[goldWhaleIds[i]] = true;
}
}
function setYachts(uint256[] calldata yachtIds) external onlyOwner {
for(uint256 i = 0; i < yachtIds.length; i++) {
isYacht[yachtIds[i]] = true;
}
}
function setWhaleRates(uint256[] calldata whaleIds, uint256 rate) external onlyOwner {
for (uint i = 0; i < whaleIds.length; i++) {
whaleIdToRate[whaleIds[i]] = rate;
}
}
function setOrcaRates(uint256[] calldata orcaIds, uint256 rate) external onlyOwner {
for (uint i = 0; i < orcaIds.length; i++) {
orcaIdToRate[orcaIds[i]] = rate;
}
}
function getDailyRateWhaleOrca(uint256 whaleId, uint256 orcaId) public view returns (uint256) {
uint256 bonusWhaleRate = whaleIdToRate[whaleId];
uint256 bonusOrcaRate = orcaIdToRate[orcaId];
if (bonusWhaleRate == 0) {
bonusWhaleRate = 1;
}
if (bonusOrcaRate == 0) {
bonusOrcaRate = 1;
}
if (bonusWhaleRate != 1 || bonusOrcaRate != 1) {
return DAILY_WHALE_ORCA_RATE * bonusWhaleRate * bonusOrcaRate;
}
bool goldWhale = isGoldWhale[whaleId];
bool yacht = isYacht[orcaId];
if (goldWhale && yacht) {
return DAILY_GOLD_WHALE_YACHT_RATE;
} else if (goldWhale) {
return DAILY_GOLD_WHALE_ORCA_RATE;
} else if (yacht) {
return DAILY_WHALE_YACHT_RATE;
} else {
return DAILY_WHALE_ORCA_RATE;
}
}
function getDailyRateWhaleWhale(uint256 whaleId, uint256 whale2Id) public view returns (uint256) {
uint256 bonusWhaleRate1 = whaleIdToRate[whaleId];
uint256 bonusWhaleRate2 = whaleIdToRate[whale2Id];
if (bonusWhaleRate1 == 0) {
bonusWhaleRate1 = 1;
}
if (bonusWhaleRate2 == 0) {
bonusWhaleRate2 = 1;
}
if (bonusWhaleRate1 != 1 || bonusWhaleRate2 != 1) {
return DAILY_WHALE_RATE * bonusWhaleRate1 * bonusWhaleRate2;
}
bool isWhale1Gold = isGoldWhale[whaleId];
bool isWhale2Gold = isGoldWhale[whale2Id];
if (isWhale1Gold && isWhale2Gold) {
return DAILY_DOUBLE_GOLD_WHALE_RATE;
} else if (isWhale1Gold || isWhale2Gold) {
return DAILY_GOLD_WHALE_RATE;
} else {
return DAILY_WHALE_RATE;
}
}
function _addWhaleAndOrcaToCigarClub(address account, uint256 whaleId, uint256 orcaId) internal {
whaleOrcaClub[whaleId] = WhaleOrcaStakeInfo({
owner: account,
orcaTokenId: uint16(orcaId),
stakeTimestamp: block.timestamp
});
emit WhaleOrcaStaked(account, whaleId, orcaId, block.timestamp);
}
function _addWhalesToCigarClub(address account, uint256 whaleId, uint256 whale2Id) internal {
whaleWhaleClub[whaleId] = WhaleWhaleStakeInfo({
owner: account,
whaleToken2Id: uint16(whale2Id),
stakeTimestamp: block.timestamp
});
emit WhaleWhaleStaked(account, whaleId, whale2Id, block.timestamp);
}
function _addWealthyWhaleToCigarClub(address account, uint256 tokenId) internal {
wealthyWhaleClub[tokenId] = WealthyWhaleStakeInfo({
owner: account,
stakeTimestamp: block.timestamp,
previousCigarVaultAmount: wealthyWhaleVault
});
totalWealthyWhalesStaked += 1;
emit WealthyWhaleStaked(account, tokenId, wealthyWhaleVault, block.timestamp);
}
function _claimWhaleOrcaAndGetReward(uint256 whaleId, bool unstake) internal returns (uint256) {
WhaleOrcaStakeInfo memory stakeInfo = whaleOrcaClub[whaleId];
require(stakeInfo.owner == _msgSender(), "This whale is owned by someone else.");
uint256 timeStaked = block.timestamp - stakeInfo.stakeTimestamp;
require(timeStaked > MIN_STAKING_TIME_WHALES, "Must have staked for at least 2 days!");
uint256 rewardRate = getDailyRateWhaleOrca(whaleId, stakeInfo.orcaTokenId);
uint256 reward = timeStaked * rewardRate / 1 days;
reward = _loadWealthyWhaleVault(reward);
if (cigarAwarded + reward > cigarStakingCap) {
reward = cigarStakingCap - cigarAwarded;
}
if (unstake) {
uint256 securityOrcaId = stakeInfo.orcaTokenId;
whales.safeTransferFrom(address(this), _msgSender(), whaleId, "");
securityOrcas.safeTransferFrom(address(this), _msgSender(), securityOrcaId, "");
delete whaleOrcaClub[whaleId];
totalWhaleOrcasStaked -= 1;
emit WhaleOrcaUnstaked(_msgSender(), whaleId, securityOrcaId, block.timestamp);
} else {
whaleOrcaClub[whaleId].stakeTimestamp = block.timestamp;
emit RewardsClaimedWhaleOrca(_msgSender(), whaleId, stakeInfo.orcaTokenId, block.timestamp);
}
cigarAwarded += reward;
return reward;
}
function _claimWhalesAndGetReward(uint256 whaleId, bool unstake) internal returns (uint256) {
WhaleWhaleStakeInfo memory stakeInfo = whaleWhaleClub[whaleId];
require(stakeInfo.owner == _msgSender(), "This whale is owned by someone else.");
uint256 timeStaked = block.timestamp - stakeInfo.stakeTimestamp;
require(timeStaked > MIN_STAKING_TIME_WHALES, "Must have staked for at least 2 days!");
uint256 rewardRate = getDailyRateWhaleWhale(whaleId, stakeInfo.whaleToken2Id);
uint256 reward = timeStaked * rewardRate / 1 days;
reward = _loadWealthyWhaleVault(reward);
if (cigarAwarded + reward > cigarStakingCap) {
reward = cigarStakingCap - cigarAwarded;
}
if (unstake) {
whales.safeTransferFrom(address(this), _msgSender(), whaleId, "");
whales.safeTransferFrom(address(this), _msgSender(), stakeInfo.whaleToken2Id, "");
delete whaleWhaleClub[whaleId];
totalWhaleWhalesStaked -= 1;
emit WhaleWhaleUnstaked(_msgSender(), whaleId, stakeInfo.whaleToken2Id, block.timestamp);
} else {
whaleWhaleClub[whaleId].stakeTimestamp = block.timestamp;
emit RewardsClaimedWhaleWhale(_msgSender(), whaleId, stakeInfo.whaleToken2Id, block.timestamp);
}
cigarAwarded += reward;
return reward;
}
function _claimWealthyWhaleAndGetReward(uint256 tokenId, bool unstake) internal returns (uint256) {
WealthyWhaleStakeInfo memory stakeInfo = wealthyWhaleClub[tokenId];
require(stakeInfo.owner == _msgSender(), "This wealthy whale is owned by someone else");
uint256 timeStaked = block.timestamp - stakeInfo.stakeTimestamp;
require(timeStaked > MIN_STAKING_TIME_WEALTHY_WHALES, "Must have staked for at least 6 days!");
uint256 reward = wealthyWhaleVault - stakeInfo.previousCigarVaultAmount;
if (cigarAwarded + reward > cigarStakingCap) {
reward = cigarStakingCap - cigarAwarded;
}
if (unstake) {
wealthyWhales.safeTransferFrom(address(this), _msgSender(), tokenId, "");
delete wealthyWhaleClub[tokenId];
totalWealthyWhalesStaked -= 1;
emit WealthyWhaleUnstaked(_msgSender(), tokenId, wealthyWhaleVault, block.timestamp);
} else {
wealthyWhaleClub[tokenId].previousCigarVaultAmount = wealthyWhaleVault;
emit RewardsClaimedWealthyWhale(_msgSender(), tokenId, wealthyWhaleVault, block.timestamp);
}
cigarAwarded += reward;
return reward;
}
function _loadWealthyWhaleVault(uint256 whaleReward) internal returns (uint256) {
uint256 wealthyWhaleTribute = whaleReward * WEALTHY_WHALE_TAX / 100;
if (totalWealthyWhalesStaked == 0) {
unclaimedWealthyWhaleVault += wealthyWhaleTribute;
} else {
wealthyWhaleVault += (wealthyWhaleTribute + unclaimedWealthyWhaleVault)
/ totalWealthyWhalesStaked;
unclaimedWealthyWhaleVault = 0;
}
return whaleReward - wealthyWhaleTribute;
}
}
文件 4 的 23:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 23:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 23:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
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;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
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;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
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;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
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;
}
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);
}
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);
}
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);
}
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 _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 7 的 23:ERC721.sol
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
文件 8 的 23:ERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
mapping(uint256 => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 => uint256) private _allTokensIndex;
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId;
_ownedTokensIndex[lastTokenId] = tokenIndex;
}
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId;
_allTokensIndex[lastTokenId] = tokenIndex;
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
文件 9 的 23:ICIGAR.sol
pragma solidity ^0.8.0;
interface ICIGAR {
function publicSaleMint(address to, uint256 amountInEther) external payable;
function mint(address to, uint256 amount) external;
function reserveToDAO(address dao) external;
function reserveToLiquidity(address liquidityHandler) external;
function reserveToTeam(address team) external;
function burn(address from, uint256 amount) external;
function addController(address controller) external;
function removeController(address controller) external;
function flipSaleState() external;
function setMintPrice(uint256 _mintPrice) external;
function setMaxMint(uint256 _maxMint) external;
function lockControllers() external;
function withdrawPublicSale() external;
}
文件 10 的 23:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 11 的 23:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 12 的 23:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 13 的 23:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 14 的 23:IERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 15 的 23:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 16 的 23:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 17 的 23:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 18 的 23:SecurityOrcas.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
abstract contract WHALES {
function ownerOf(uint256 tokenId) public view virtual returns (address);
function balanceOf(address owner) public view virtual returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256);
}
contract SecurityOrcas is ERC721, ERC721Enumerable, Ownable {
WHALES private whales;
string public PROVENANCE;
bool public saleIsActive = false;
uint256 public MAX_TOKENS = 10000;
uint256 public MAX_MINT = 50;
string private _baseURIextended;
event PermanentURI(string _value, uint256 indexed _id);
constructor(address whalesContract) ERC721("SSoW Security Orcas", "SO") {
whales = WHALES(whalesContract);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function setProvenance(string memory provenance) public onlyOwner {
PROVENANCE = provenance;
}
function flipSaleState() public onlyOwner {
saleIsActive = !saleIsActive;
}
function mintToken(uint256 tokenId) public {
require(saleIsActive, "Sale must be active to mint Security Orcas");
require(totalSupply() < MAX_TOKENS, "Purchase would exceed max supply of tokens");
require(tokenId < MAX_TOKENS, "TokenId does not exist");
require(!_exists(tokenId), "TokenId has already been minted");
require(whales.ownerOf(tokenId) == msg.sender, "Sender does not own the correct Whale token");
_safeMint(msg.sender, tokenId);
}
function mintMultipleTokens(uint256 startingIndex, uint256 numberOfTokens) public {
require(saleIsActive, "Sale must be active to mint Security Orcas");
require(numberOfTokens > 0, "Need to mint at least one token");
require(numberOfTokens <= MAX_MINT, "Cannot adopt more than 50 Orcas in one tx");
require(whales.balanceOf(msg.sender) >= numberOfTokens + startingIndex, "Sender does not own the correct number of Whale tokens");
for(uint i = 0; i < numberOfTokens; i++) {
require(totalSupply() < MAX_TOKENS, "Cannot exceed max supply of tokens");
uint tokenId = whales.tokenOfOwnerByIndex(msg.sender, i + startingIndex);
if(!_exists(tokenId)) {
_safeMint(msg.sender, tokenId);
}
}
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
function markPermanentURI(string memory value, uint256 id) public onlyOwner {
emit PermanentURI(value, id);
}
}
文件 19 的 23:SimpleToken.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "../staking/CIGAR.sol";
import "../WealthyWhales.sol";
contract SimpleToken is Context, Ownable, ERC721, ERC721Enumerable {
uint public constant MINT_PRICE = 100 ether;
CIGAR public cigar;
address public wealthyWhales;
mapping(address => mapping(uint256 => uint256)) public userToTokenTypes;
uint256 public numTypes;
constructor() ERC721("TreasureChest", "TC"){
numTypes = 5;
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function mint(uint256 amount) external {
uint256 totalCost = 0;
for(uint i = 0; i < amount; i++) {
uint256 rand = random(i);
uint256 itemType = rand % numTypes;
userToTokenTypes[_msgSender()][itemType]++;
totalCost += MINT_PRICE;
}
cigar.burn(_msgSender(), totalCost);
}
function burn(address user, bool burnGems) external {
require(_msgSender() == wealthyWhales, "Must be called by WealthyWhales");
if (burnGems) {
userToTokenTypes[user][1]--;
userToTokenTypes[user][2]--;
userToTokenTypes[user][3]--;
} else {
userToTokenTypes[user][4]--;
}
}
function setExternalContracts(address wealthyWhalesAddress, address cigarToken) public onlyOwner {
require(wealthyWhales == address(0) && address(cigar) == address(0), "External contracts already initialized");
wealthyWhales = wealthyWhalesAddress;
cigar = CIGAR(cigarToken);
}
function random(uint256 seed) internal view returns (uint256) {
return uint256(keccak256(abi.encodePacked(
tx.origin,
blockhash(block.number - 1),
block.timestamp,
seed
)));
}
}
文件 20 的 23:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
文件 21 的 23:TreasureChest.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "../interfaces/ICIGAR.sol";
contract TreasureChest is Context, ERC721, ERC721Enumerable, Ownable {
uint256 public constant NUM_TYPES = 5;
uint256 public mintPrice = 20000 ether;
string private _baseURIextended;
mapping(address => uint256[5]) public userToTokenTypes;
mapping(address => bool) public controllers;
ICIGAR public cigar;
bool public chestIsOpen;
uint256 public nftChance;
uint256 public currentNftCount;
uint256 public nftMaxCount;
event PermanentURI(string _value, uint256 indexed _id);
constructor() ERC721("Treasure Chest", "TC") {
chestIsOpen = true;
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function mint(uint256 amount) public {
require(chestIsOpen, "Chest must be open!");
uint256 totalCost = 0;
for(uint i = 0; i < amount; i++) {
uint256 rand = random(i);
uint256 itemType = getType(rand % 100);
userToTokenTypes[_msgSender()][itemType]++;
totalCost += mintPrice;
}
cigar.burn(_msgSender(), totalCost);
}
function mintGem(uint256 amount, uint256 gemType) external {
require(chestIsOpen, "Chest must be open!");
require(gemType == 1 || gemType == 2 || gemType == 3, "GemType must be 1, 2, or 3");
uint256 totalCost = 0;
for(uint i = 0; i < amount; i++) {
uint256 rand = random(i);
uint256 rand2 = rand % 10;
if (rand2 < 4) {
userToTokenTypes[_msgSender()][gemType]++;
} else {
userToTokenTypes[_msgSender()][0]++;
}
totalCost += mintPrice;
}
cigar.burn(_msgSender(), totalCost);
}
function mintDiamond(uint256 amount) external {
require(chestIsOpen, "Chest must be open!");
uint256 totalCost = 0;
for(uint i = 0; i < amount; i++) {
uint256 rand = random(i);
uint256 rand2 = rand % 7;
if (rand2 == 0) {
userToTokenTypes[_msgSender()][4]++;
} else {
userToTokenTypes[_msgSender()][0]++;
}
totalCost += mintPrice;
}
cigar.burn(_msgSender(), totalCost);
}
function superMint(uint256 amount) external {
require(chestIsOpen, "Chest must be open!");
uint256 supply = totalSupply();
uint256 numMinted = 0;
uint256 nftsMinted = 0;
uint256 totalCost = 0;
for(uint i = 0; i < amount; i++) {
if (currentNftCount < nftMaxCount) {
uint256 rand = random(i);
uint256 rand2 = rand % 10000;
if (rand2 < nftChance) {
_safeMint(_msgSender(), supply + nftsMinted);
nftsMinted++;
currentNftCount++;
totalCost += mintPrice;
} else {
mint(1);
}
numMinted++;
} else {
break;
}
}
cigar.burn(_msgSender(), totalCost);
mint(amount - numMinted);
}
function reserveTokens(uint256 numTokens) external onlyOwner {
uint supply = totalSupply();
uint i;
for (i = 0; i < numTokens; i++) {
_safeMint(msg.sender, supply + i);
}
}
function burn(address user, uint256[5] calldata amounts) external {
require(controllers[_msgSender()], "Must be called by a valid controller address");
for(uint256 i = 0; i < 5; i++) {
userToTokenTypes[user][i] -= amounts[i];
}
}
function setNftMintInfo(uint256 chance, uint256 maxCount) external onlyOwner {
require(chance <= 10000, "Chance must be less than 10000");
nftChance = chance;
nftMaxCount = maxCount;
currentNftCount = 0;
}
function adjustTreasureChestPrice(uint256 newPrice) external onlyOwner {
mintPrice = newPrice;
}
function setCigarToken(address cigarToken) external onlyOwner {
require(address(cigar) == address(0), "Cigar Token already set.");
cigar = ICIGAR(cigarToken);
}
function setController(address controller) external onlyOwner {
controllers[controller] = !controllers[controller];
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
function closeOrOpenChest(bool open) external onlyOwner {
chestIsOpen = open;
}
function markPermanentURI(string memory value, uint256 id) public onlyOwner {
emit PermanentURI(value, id);
}
function getTokensForUser(address user) external view returns (uint256[5] memory) {
return userToTokenTypes[user];
}
function random(uint256 seed) internal view returns (uint256) {
return uint256(keccak256(abi.encodePacked(
tx.origin,
blockhash(block.number - 1),
block.timestamp,
seed
)));
}
function getType(uint256 rand) internal pure returns (uint256) {
if (rand < 35) {
return 0;
} else if (rand < 40) {
return 4;
} else if (rand < 60) {
return 1;
} else if (rand < 80) {
return 2;
} else {
return 3;
}
}
}
文件 22 的 23:WealthyWhales.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "./staking/CigarClub.sol";
import "./staking/TreasureChest.sol";
import "./experimental/SimpleToken.sol";
contract WealthyWhales is Context, ERC721, ERC721Enumerable, Ownable {
string public PROVENANCE;
bool public saleIsActive = false;
CigarClub public cigarClub;
TreasureChest public treasureChest;
uint256 public constant MAX_TOKENS = 1000;
string private _baseURIextended;
event PermanentURI(string _value, uint256 indexed _id);
constructor(address _treasureChest) ERC721("Wealthy Whales", "WW") {
treasureChest = TreasureChest(_treasureChest);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function setProvenance(string memory provenance) public onlyOwner {
PROVENANCE = provenance;
}
function flipSaleState() public onlyOwner {
require(address(cigarClub) != address(0), "The CigarClub has not been initialized");
saleIsActive = !saleIsActive;
}
function mintWithGems(uint numberOfWealthyWhales) external {
require(numberOfWealthyWhales > 0, "Must mint at least 1 wealthy whale");
require(saleIsActive, "Sale must be active to mint Tokens");
uint256 totalSupply = totalSupply();
require(totalSupply + numberOfWealthyWhales <= MAX_TOKENS, "Purchase would exceed max supply of tokens");
uint256 numSapphires = treasureChest.userToTokenTypes(_msgSender(), 1);
uint256 numEmeralds = treasureChest.userToTokenTypes(_msgSender(), 2);
uint256 numRubies = treasureChest.userToTokenTypes(_msgSender(), 3);
require(numSapphires >= numberOfWealthyWhales, "Must have enough sapphires");
require(numEmeralds >= numberOfWealthyWhales, "Must have enough emeralds");
require(numRubies >= numberOfWealthyWhales, "Must have enough rubies");
for(uint i = 0; i < numberOfWealthyWhales; i++) {
_safeMint(_msgSender(), totalSupply);
totalSupply++;
}
uint256[5] memory tokensToSpend = [0, numberOfWealthyWhales, numberOfWealthyWhales, numberOfWealthyWhales, 0];
treasureChest.burn(_msgSender(), tokensToSpend);
}
function mintWithDiamonds(uint numberOfWealthyWhales) external {
require(numberOfWealthyWhales > 0, "Must mint at least 1 wealthy whale");
require(saleIsActive, "Sale must be active to mint Tokens");
uint256 totalSupply = totalSupply();
require(totalSupply + numberOfWealthyWhales <= MAX_TOKENS, "Purchase would exceed max supply of tokens");
uint256 numDiamonds = treasureChest.userToTokenTypes(_msgSender(), 4);
require(numDiamonds >= numberOfWealthyWhales, "Must have enough diamonds");
for(uint i = 0; i < numberOfWealthyWhales; i++) {
_safeMint(_msgSender(), totalSupply);
totalSupply++;
}
uint256[5] memory tokensToSpend = [0, 0, 0, 0, numberOfWealthyWhales];
treasureChest.burn(_msgSender(), tokensToSpend);
}
function mintWithSanddollars(uint numberOfWealthyWhales) external {
require(numberOfWealthyWhales > 0, "Must mint at least 1 wealthy whale");
require(saleIsActive, "Sale must be active to mint Tokens");
uint256 totalSupply = totalSupply();
require(totalSupply + numberOfWealthyWhales <= MAX_TOKENS, "Purchase would exceed max supply of tokens");
uint256 numSanddollars = treasureChest.userToTokenTypes(_msgSender(), 0);
require(numSanddollars >= numberOfWealthyWhales * 100, "Must have enough sand dollars");
for(uint i = 0; i < numberOfWealthyWhales; i++) {
_safeMint(_msgSender(), totalSupply);
totalSupply++;
}
uint256[5] memory tokensToSpend = [numberOfWealthyWhales * 100, 0, 0, 0, 0];
treasureChest.burn(_msgSender(), tokensToSpend);
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
if (_msgSender() != address(cigarClub)) {
require(_isApprovedOrOwner(_msgSender(), tokenId), "");
}
_transfer(from, to, tokenId);
}
function setCigarClub(address _cigarClub) external onlyOwner {
require(address(cigarClub) == address(0), "CigarClub has already been initialized.");
cigarClub = CigarClub(_cigarClub);
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
function markPermanentURI(string memory value, uint256 id) public onlyOwner {
emit PermanentURI(value, id);
}
}
文件 23 的 23:Whales.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
contract Whales is ERC721, ERC721Enumerable, Ownable {
string public PROVENANCE;
uint256 public constant tokenPrice = 50000000000000000;
uint public constant maxTokenPurchase = 10;
uint256 public MAX_TOKENS = 10000;
bool public saleIsActive = false;
string private _baseURIextended;
constructor() ERC721("Secret Society of Whales", "SSOW") {
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function setProvenance(string memory provenance) public onlyOwner {
PROVENANCE = provenance;
}
function reserveTokens() public onlyOwner {
uint supply = totalSupply();
require(supply < 200, "More than 200 tokens have already been reserved or minted.");
uint i;
for (i = 0; i < 100; i++) {
_safeMint(msg.sender, supply + i);
}
}
function flipSaleState() public onlyOwner {
saleIsActive = !saleIsActive;
}
function mintToken(uint numberOfTokens) public payable {
require(saleIsActive, "Sale must be active to mint Tokens");
require(numberOfTokens <= maxTokenPurchase, "Exceeded max token purchase");
require(totalSupply() + numberOfTokens <= MAX_TOKENS, "Purchase would exceed max supply of tokens");
require(tokenPrice * numberOfTokens <= msg.value, "Ether value sent is not correct");
for(uint i = 0; i < numberOfTokens; i++) {
uint mintIndex = totalSupply();
if (totalSupply() < MAX_TOKENS) {
_safeMint(msg.sender, mintIndex);
}
}
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
}
{
"compilationTarget": {
"contracts/staking/CigarClub.sol": "CigarClub"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_whales","type":"address"},{"internalType":"address","name":"_securityOrcas","type":"address"},{"internalType":"address","name":"_cigar","type":"address"},{"internalType":"address","name":"_wealthyWhales","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wealthyWhaleVault","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RewardsClaimedWealthyWhale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"whaleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orcaId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RewardsClaimedWhaleOrca","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"whaleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"whale2Id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RewardsClaimedWhaleWhale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wealthyWhaleVault","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WealthyWhaleStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wealthyWhaleVault","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WealthyWhaleUnstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"whaleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orcaId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WhaleOrcaStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"whaleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orcaId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WhaleOrcaUnstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"whaleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"whale2Id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WhaleWhaleStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"whaleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"whale2Id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WhaleWhaleUnstaked","type":"event"},{"inputs":[],"name":"DAILY_DOUBLE_GOLD_WHALE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAILY_GOLD_WHALE_ORCA_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAILY_GOLD_WHALE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAILY_GOLD_WHALE_YACHT_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAILY_WHALE_ORCA_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAILY_WHALE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAILY_WHALE_YACHT_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_STAKING_TIME_WEALTHY_WHALES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_STAKING_TIME_WHALES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEALTHY_WHALE_TAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZERO_WHALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cigar","outputs":[{"internalType":"contract CIGAR","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cigarAwarded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cigarStakingCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bool","name":"unstake","type":"bool"}],"name":"claimWealthyWhales","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"whaleIds","type":"uint256[]"},{"internalType":"bool","name":"unstake","type":"bool"}],"name":"claimWhales","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"whaleIds","type":"uint256[]"},{"internalType":"bool","name":"unstake","type":"bool"}],"name":"claimWhalesAndOrcas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"whaleId","type":"uint256"},{"internalType":"uint256","name":"orcaId","type":"uint256"}],"name":"getDailyRateWhaleOrca","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"whaleId","type":"uint256"},{"internalType":"uint256","name":"whale2Id","type":"uint256"}],"name":"getDailyRateWhaleWhale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isGoldWhale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isYacht","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"orcaIdToRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"retrieveLoneWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"securityOrcas","outputs":[{"internalType":"contract SecurityOrcas","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"goldWhaleIds","type":"uint256[]"}],"name":"setGoldWhales","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"orcaIds","type":"uint256[]"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setOrcaRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"whaleIds","type":"uint256[]"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setWhaleRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"yachtIds","type":"uint256[]"}],"name":"setYachts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stakeWealthyWhalesInCigarClub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"whaleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"orcaIds","type":"uint256[]"}],"name":"stakeWhalesAndOrcasInCigarClub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"whaleIds","type":"uint256[]"}],"name":"stakeWhalesInCigarClub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalWealthyWhalesStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWhaleOrcasStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWhaleWhalesStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unclaimedWealthyWhaleVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"wealthyWhaleClub","outputs":[{"internalType":"uint256","name":"previousCigarVaultAmount","type":"uint256"},{"internalType":"uint256","name":"stakeTimestamp","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wealthyWhaleVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wealthyWhales","outputs":[{"internalType":"contract WealthyWhales","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whaleIdToRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whaleOrcaClub","outputs":[{"internalType":"uint16","name":"orcaTokenId","type":"uint16"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"stakeTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whaleStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whaleWhaleClub","outputs":[{"internalType":"uint16","name":"whaleToken2Id","type":"uint16"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"stakeTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whales","outputs":[{"internalType":"contract Whales","name":"","type":"address"}],"stateMutability":"view","type":"function"}]