update
This commit is contained in:
parent
efadddcde6
commit
b8793df4f8
14
contracts/ERC.sol
Normal file
14
contracts/ERC.sol
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
pragma solidity ^0.8.15;
|
||||||
|
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||||
|
|
||||||
|
contract ERC is ERC20 {
|
||||||
|
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function mint(address to, uint256 amount) public {
|
||||||
|
_mint(to, amount);
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ contract Marketplace is Initializable {
|
|||||||
address payable seller;
|
address payable seller;
|
||||||
uint256 tokenId;
|
uint256 tokenId;
|
||||||
uint256 price;
|
uint256 price;
|
||||||
|
bool bought;
|
||||||
|
bool cancelled;
|
||||||
}
|
}
|
||||||
mapping(uint256 => Sale) saleIdToSale;
|
mapping(uint256 => Sale) saleIdToSale;
|
||||||
|
|
||||||
@ -48,22 +50,22 @@ contract Marketplace is Initializable {
|
|||||||
|
|
||||||
//modifiers
|
//modifiers
|
||||||
modifier isExistingSale(uint256 saleId) {
|
modifier isExistingSale(uint256 saleId) {
|
||||||
require(saleIdToSale[saleId].price != 0);
|
require(saleIdToSale[saleId].price != 0, "!exists");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlySaleOwner(uint256 saleId) {
|
modifier onlySaleOwner(uint256 saleId) {
|
||||||
require(saleIdToSale[saleId].seller == msg.sender);
|
require(saleIdToSale[saleId].seller == msg.sender, "!seller");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyValidPrice(uint256 price) {
|
modifier onlyValidPrice(uint256 price) {
|
||||||
require(price > 0);
|
require(price > 0, "!price");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyAdmin() {
|
modifier onlyAdmin() {
|
||||||
require(treasury.isAdmin(msg.sender));
|
require(treasury.isAdmin(msg.sender), "!admin");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +107,7 @@ contract Marketplace is Initializable {
|
|||||||
onlyValidPrice(price)
|
onlyValidPrice(price)
|
||||||
{
|
{
|
||||||
currentSaleId++;
|
currentSaleId++;
|
||||||
Sale memory sale = saleIdToSale[currentSaleId];
|
Sale storage sale = saleIdToSale[currentSaleId];
|
||||||
sale.seller = payable(msg.sender);
|
sale.seller = payable(msg.sender);
|
||||||
sale.price = price;
|
sale.price = price;
|
||||||
sale.tokenId = tokenId;
|
sale.tokenId = tokenId;
|
||||||
@ -114,9 +116,11 @@ contract Marketplace is Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cancelSale(uint256 saleId) public onlySaleOwner(saleId) {
|
function cancelSale(uint256 saleId) public onlySaleOwner(saleId) {
|
||||||
Sale memory sale = saleIdToSale[saleId];
|
Sale storage sale = saleIdToSale[saleId];
|
||||||
|
require(!sale.bought, "bought");
|
||||||
|
require(!sale.cancelled, "cancelled");
|
||||||
nft.transferFrom(address(this), msg.sender, sale.tokenId);
|
nft.transferFrom(address(this), msg.sender, sale.tokenId);
|
||||||
delete sale;
|
sale.cancelled = true;
|
||||||
emit SaleCancelled(saleId);
|
emit SaleCancelled(saleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,22 +130,27 @@ contract Marketplace is Initializable {
|
|||||||
onlyValidPrice(price)
|
onlyValidPrice(price)
|
||||||
isExistingSale(saleId)
|
isExistingSale(saleId)
|
||||||
{
|
{
|
||||||
Sale memory sale = saleIdToSale[saleId];
|
Sale storage sale = saleIdToSale[saleId];
|
||||||
|
require(!sale.bought, "bought");
|
||||||
|
require(!sale.cancelled, "cancelled");
|
||||||
uint256 oldPrice = sale.price;
|
uint256 oldPrice = sale.price;
|
||||||
sale.price = price;
|
sale.price = price;
|
||||||
emit SaleUpdated(saleId, oldPrice, price);
|
emit SaleUpdated(saleId, oldPrice, price);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buyToken(uint256 saleId) public isExistingSale(saleId) {
|
function buyToken(uint256 saleId) public isExistingSale(saleId) {
|
||||||
Sale memory sale = saleIdToSale[saleId];
|
Sale storage sale = saleIdToSale[saleId];
|
||||||
|
require(!sale.bought, "bought");
|
||||||
|
require(!sale.cancelled, "cancelled");
|
||||||
nft.transferFrom(address(this), msg.sender, sale.tokenId);
|
nft.transferFrom(address(this), msg.sender, sale.tokenId);
|
||||||
_distributeFunds(sale.price, sale.seller);
|
_distributeFunds(sale.price, sale.seller);
|
||||||
|
sale.bought = true;
|
||||||
emit TokenBought(saleId, msg.sender, sale.tokenId, sale.price);
|
emit TokenBought(saleId, msg.sender, sale.tokenId, sale.price);
|
||||||
}
|
}
|
||||||
|
|
||||||
//admin functions
|
//admin functions
|
||||||
function changeFees(uint256 _fee) public onlyAdmin {
|
function changeFees(uint256 _fee) public onlyAdmin {
|
||||||
require(_fee > 0 && _fee < 2000);
|
require(_fee > 0 && _fee < 2000, "wrong arg");
|
||||||
emit FeesChanged(msg.sender, fee, _fee);
|
emit FeesChanged(msg.sender, fee, _fee);
|
||||||
fee = _fee;
|
fee = _fee;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,9 @@ import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeab
|
|||||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||||
import "@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol";
|
import "@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol";
|
||||||
import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";
|
import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||||
import "./interfaces/ITreasury.sol";
|
import "./interfaces/ITreasury.sol";
|
||||||
import "./interfaces/IPancake.sol";
|
import "./interfaces/IPancakeSwapPair.sol";
|
||||||
import "./mixins/signature-control.sol";
|
import "./mixins/signature-control.sol";
|
||||||
|
|
||||||
contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
||||||
@ -16,7 +17,7 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
using SafeERC20Upgradeable for IERC20Upgradeable;
|
using SafeERC20Upgradeable for IERC20Upgradeable;
|
||||||
|
|
||||||
//variables
|
//variables
|
||||||
bool pause = true;
|
bool pause;
|
||||||
uint256 nonce;
|
uint256 nonce;
|
||||||
ITreasury treasury;
|
ITreasury treasury;
|
||||||
IERC20Upgradeable BoM;
|
IERC20Upgradeable BoM;
|
||||||
@ -40,7 +41,8 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
|
|
||||||
//mint prices, caps, addresses of reward tokens(shiba,floki,doggy,doge)
|
//mint prices, caps, addresses of reward tokens(shiba,floki,doggy,doge)
|
||||||
uint256[4] prices = [
|
uint256[4] prices = [
|
||||||
300 * 10**18,
|
.001 ether,
|
||||||
|
// 300 * 10**18,
|
||||||
250 * 10**18,
|
250 * 10**18,
|
||||||
200 * 10**18,
|
200 * 10**18,
|
||||||
250 * 10**18
|
250 * 10**18
|
||||||
@ -51,9 +53,9 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
uint256[4] nftCaps = [1000, 1500, 2000, 1500];
|
uint256[4] nftCaps = [1000, 1500, 2000, 1500];
|
||||||
address[4] public rewardTokens = [
|
address[4] public rewardTokens = [
|
||||||
0x0000000000000000000000000000000000000000,
|
0x0000000000000000000000000000000000000000,
|
||||||
0x0000000000000000000000000000000000000000,
|
0x0000000000000000000000000000000000000001,
|
||||||
0x0000000000000000000000000000000000000000,
|
0x0000000000000000000000000000000000000002,
|
||||||
0x0000000000000000000000000000000000000000
|
0x0000000000000000000000000000000000000003
|
||||||
];
|
];
|
||||||
mapping(address => uint256) addressToType;
|
mapping(address => uint256) addressToType;
|
||||||
mapping(address => uint256) totalRatesForType;
|
mapping(address => uint256) totalRatesForType;
|
||||||
@ -123,43 +125,43 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
|
|
||||||
//modifiers
|
//modifiers
|
||||||
modifier onlyAdmin() {
|
modifier onlyAdmin() {
|
||||||
require(treasury.isAdmin(msg.sender));
|
require(treasury.isAdmin(msg.sender), "!admin");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier isUnpaused() {
|
modifier isUnpaused() {
|
||||||
require(!pause);
|
require(!pause, "paused");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier isValidWhitelistMint(uint256 amount, uint256 tokenType) {
|
modifier isValidWhitelistMint(uint256 amount, uint256 tokenType) {
|
||||||
require(isPresale);
|
require(isPresale, "!presale");
|
||||||
require(isWhitelisted[msg.sender]);
|
require(isWhitelisted[msg.sender], "!whitelisted");
|
||||||
require(
|
require(
|
||||||
mintedOnWhitelist[msg.sender] + amount <=
|
mintedOnWhitelist[msg.sender] + amount <=
|
||||||
maxMintPerAddressDuringWhitelist
|
maxMintPerAddressDuringWhitelist, "maxMint exceeded"
|
||||||
);
|
);
|
||||||
require(tokenType <= 3);
|
require(tokenType <= 3, "!tokenType");
|
||||||
require(
|
require(
|
||||||
whitelistMintCapOfToken[tokenType] + amount <=
|
whitelistMintCapOfToken[tokenType] + amount <=
|
||||||
whitelistMintCapPerType
|
whitelistMintCapPerType, "mintCap exceeded"
|
||||||
);
|
);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier isValidMint(uint256 amount, uint256 tokenType) {
|
modifier isValidMint(uint256 amount, uint256 tokenType) {
|
||||||
require(!isPresale);
|
require(!isPresale, "(mint) presale");
|
||||||
require(tokenType <= 3);
|
require(tokenType <= 3, "!tokenType");
|
||||||
require(mintCapOfToken[tokenType] + amount <= nftCaps[tokenType]);
|
require(mintCapOfToken[tokenType] + amount <= nftCaps[tokenType]);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier isValidCombine(uint256[] memory tokenIds) {
|
modifier isValidCombine(uint256[] memory tokenIds) {
|
||||||
require(tokenIds.length > 1 && tokenIds.length <= 4);
|
require(tokenIds.length > 1 && tokenIds.length <= 4, "wrong tokenIds length");
|
||||||
bool hasDupes;
|
bool hasDupes;
|
||||||
for (uint256 i = 0; i < tokenIds.length; i++) {
|
for (uint256 i = 0; i < tokenIds.length; i++) {
|
||||||
require(ownerOf(tokenIds[i]) == msg.sender);
|
require(ownerOf(tokenIds[i]) == msg.sender, "!owner");
|
||||||
require(tokenIdToType[tokenIds[i]].length == 1);
|
require(tokenIdToType[tokenIds[i]].length == 1, "!tokenIdToType");
|
||||||
for (uint256 index = i; index < tokenIds.length; index++) {
|
for (uint256 index = i; index < tokenIds.length; index++) {
|
||||||
if (
|
if (
|
||||||
index != i &&
|
index != i &&
|
||||||
@ -169,7 +171,7 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
hasDupes = true;
|
hasDupes = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require(!hasDupes);
|
require(!hasDupes, "dupes");
|
||||||
}
|
}
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
@ -230,9 +232,10 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
{
|
{
|
||||||
for (uint256 i = 0; i < amount; i++) {
|
for (uint256 i = 0; i < amount; i++) {
|
||||||
supply++;
|
supply++;
|
||||||
_mint(msg.sender, supply);
|
tokenIdToInfo[supply].tokens.push(rewardTokens[tokenType]);
|
||||||
tokenIdToType[supply].push(rewardTokens[tokenType]);
|
tokenIdToType[supply].push(rewardTokens[tokenType]);
|
||||||
uint256 rate = createTokenStats(supply);
|
uint256 rate = createTokenStats(supply);
|
||||||
|
_mint(msg.sender, supply);
|
||||||
emit TokenMinted(msg.sender, supply, rewardTokens[tokenType], rate);
|
emit TokenMinted(msg.sender, supply, rewardTokens[tokenType], rate);
|
||||||
}
|
}
|
||||||
mintedOnWhitelist[msg.sender] += amount;
|
mintedOnWhitelist[msg.sender] += amount;
|
||||||
@ -249,9 +252,10 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
{
|
{
|
||||||
for (uint256 i = 0; i < amount; i++) {
|
for (uint256 i = 0; i < amount; i++) {
|
||||||
supply++;
|
supply++;
|
||||||
_mint(msg.sender, supply);
|
|
||||||
tokenIdToInfo[supply].tokens.push(rewardTokens[tokenType]);
|
tokenIdToInfo[supply].tokens.push(rewardTokens[tokenType]);
|
||||||
|
tokenIdToType[supply].push(rewardTokens[tokenType]);
|
||||||
uint256 rate = createTokenStats(supply);
|
uint256 rate = createTokenStats(supply);
|
||||||
|
_mint(msg.sender, supply);
|
||||||
emit TokenMinted(msg.sender, supply, rewardTokens[tokenType], rate);
|
emit TokenMinted(msg.sender, supply, rewardTokens[tokenType], rate);
|
||||||
}
|
}
|
||||||
mintCapOfToken[tokenType] += amount;
|
mintCapOfToken[tokenType] += amount;
|
||||||
@ -264,15 +268,15 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
payable
|
payable
|
||||||
isUnpaused
|
isUnpaused
|
||||||
{
|
{
|
||||||
require(msg.value == 0.05 ether);
|
require(msg.value == 0.05 ether, "!value");
|
||||||
supply++;
|
supply++;
|
||||||
uint256 price;
|
uint256 price;
|
||||||
_mint(msg.sender, supply);
|
|
||||||
address[] memory tokens = new address[](tokenIds.length);
|
address[] memory tokens = new address[](tokenIds.length);
|
||||||
for (uint256 i = 0; i < tokenIds.length; i++) {
|
for (uint256 i = 0; i < tokenIds.length; i++) {
|
||||||
TokenInfo storage token = tokenIdToInfo[tokenIds[i]];
|
TokenInfo memory token = tokenIdToInfo[tokenIds[i]];
|
||||||
address intermediateStorageForToken = tokenIdToType[tokenIds[i]][0];
|
address intermediateStorageForToken = tokenIdToType[tokenIds[i]][0];
|
||||||
tokenIdToInfo[supply].tokens.push(intermediateStorageForToken);
|
tokenIdToInfo[supply].tokens.push(intermediateStorageForToken);
|
||||||
|
tokenIdToType[supply].push(intermediateStorageForToken);
|
||||||
tokens[i] = intermediateStorageForToken;
|
tokens[i] = intermediateStorageForToken;
|
||||||
_burn(tokenIds[i]);
|
_burn(tokenIds[i]);
|
||||||
price += tokenToPrices[tokenIdToType[tokenIds[i]][0]] / 4;
|
price += tokenToPrices[tokenIdToType[tokenIds[i]][0]] / 4;
|
||||||
@ -281,7 +285,9 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint256 rate = createTokenStats(supply);
|
uint256 rate = createTokenStats(supply);
|
||||||
|
_mint(msg.sender, supply);
|
||||||
emit TokenCombined(msg.sender, tokenIds, tokens, supply, rate);
|
emit TokenCombined(msg.sender, tokenIds, tokens, supply, rate);
|
||||||
|
|
||||||
//TBD: calculate price with usd in mind
|
//TBD: calculate price with usd in mind
|
||||||
_distributeFunds(price);
|
_distributeFunds(price);
|
||||||
}
|
}
|
||||||
@ -455,7 +461,7 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
address path0,
|
address path0,
|
||||||
address path1
|
address path1
|
||||||
) internal view returns (uint256[] memory) {
|
) internal view returns (uint256[] memory) {
|
||||||
address[] memory path;
|
address[] memory path = new address[](2);
|
||||||
path[0] = path0;
|
path[0] = path0;
|
||||||
path[1] = path1;
|
path[1] = path1;
|
||||||
return swapRouter.getAmountsIn(price, path);
|
return swapRouter.getAmountsIn(price, path);
|
||||||
@ -467,7 +473,8 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
address path0,
|
address path0,
|
||||||
address path1
|
address path1
|
||||||
) internal returns (uint256[] memory) {
|
) internal returns (uint256[] memory) {
|
||||||
address[] memory path;
|
IERC20(path0).approve(address(swapRouter), 2**256-1);
|
||||||
|
address[] memory path = new address[](2);
|
||||||
path[0] = path0;
|
path[0] = path0;
|
||||||
path[1] = path1;
|
path[1] = path1;
|
||||||
return
|
return
|
||||||
@ -606,10 +613,11 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
function _addToPool(uint256 amount) internal {
|
function _addToPool(uint256 amount) internal {
|
||||||
uint256 lotteryPoolAmount = amount / 10;
|
uint256 lotteryPoolAmount = amount / 10;
|
||||||
|
|
||||||
address[] memory path;
|
address[] memory path = new address[](2);
|
||||||
path[0] = address(BoM);
|
path[0] = address(BoM);
|
||||||
|
|
||||||
path[1] = address(BUSD);
|
path[1] = address(BUSD);
|
||||||
|
|
||||||
|
IERC20(address(BoM)).approve(address(swapRouter), amount);
|
||||||
uint256 swappedFor = swapRouter.swapExactTokensForTokens(
|
uint256 swappedFor = swapRouter.swapExactTokensForTokens(
|
||||||
lotteryPoolAmount, // 10% to lottery
|
lotteryPoolAmount, // 10% to lottery
|
||||||
0,
|
0,
|
||||||
@ -637,38 +645,38 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
emit RewardPoolRaised(swappedFor);
|
emit RewardPoolRaised(swappedFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _afterTokenTransfer(
|
// function _afterTokenTransfer(
|
||||||
address from,
|
// address from,
|
||||||
address to,
|
// address to,
|
||||||
uint256 tokenId
|
// uint256 tokenId
|
||||||
) internal virtual override {
|
// ) internal virtual override {
|
||||||
super._afterTokenTransfer(from, to, tokenId);
|
// super._afterTokenTransfer(from, to, tokenId);
|
||||||
TokenInfo memory info = tokenIdToInfo[tokenId];
|
// TokenInfo memory info = tokenIdToInfo[tokenId];
|
||||||
if (from != address(0)) {
|
// if (from != address(0)) {
|
||||||
if (ERC721Upgradeable.balanceOf(from) == 0) {
|
// if (ERC721Upgradeable.balanceOf(from) == 0) {
|
||||||
_holders.remove(from);
|
// _holders.remove(from);
|
||||||
}
|
// }
|
||||||
if (info.tokens.length > 1) {
|
// if (info.tokens.length > 1) {
|
||||||
totalShares[4] -= info.rate;
|
// totalShares[4] -= info.rate;
|
||||||
accountShares[from][4] -= info.rate;
|
// accountShares[from][4] -= info.rate;
|
||||||
} else {
|
// } else {
|
||||||
uint256 idx = addressToType[info.tokens[0]];
|
// uint256 idx = addressToType[info.tokens[0]];
|
||||||
totalShares[idx] -= info.rate;
|
// totalShares[idx] -= info.rate;
|
||||||
accountShares[from][idx] -= info.rate;
|
// accountShares[from][idx] -= info.rate;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (to != address(0)) {
|
// if (to != address(0)) {
|
||||||
_holders.add(to);
|
// _holders.add(to);
|
||||||
if (info.tokens.length > 1) {
|
// if (info.tokens.length > 1) {
|
||||||
totalShares[4] += info.rate;
|
//// totalShares[4] += info.rate;
|
||||||
accountShares[to][4] += info.rate;
|
//// accountShares[to][4] += info.rate;
|
||||||
} else {
|
// } else {
|
||||||
uint256 idx = addressToType[info.tokens[0]];
|
//// uint256 idx = addressToType[info.tokens[0]];
|
||||||
totalShares[idx] += info.rate;
|
//// totalShares[idx] += info.rate;
|
||||||
accountShares[from][idx] += info.rate;
|
//// accountShares[to][idx] += info.rate;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
function pendingReward(uint256 idx, address account) public view returns (uint256) {
|
function pendingReward(uint256 idx, address account) public view returns (uint256) {
|
||||||
return accountShares[account][idx] + (_rewardPerShare(idx) - accountRewardsPerTokenPaid[account][idx]) / 1e18 + accountRewards[account][idx];
|
return accountShares[account][idx] + (_rewardPerShare(idx) - accountRewardsPerTokenPaid[account][idx]) / 1e18 + accountRewards[account][idx];
|
||||||
@ -697,7 +705,8 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
require(reward > 0, "nothing to claim");
|
require(reward > 0, "nothing to claim");
|
||||||
accountRewards[msg.sender][idx] = 0;
|
accountRewards[msg.sender][idx] = 0;
|
||||||
|
|
||||||
address[] memory path;
|
IERC20(address(WETH)).approve(address(swapRouter), reward);
|
||||||
|
address[] memory path = new address[](2);
|
||||||
path[0] = address(WETH);
|
path[0] = address(WETH);
|
||||||
path[1] = rewardTokens[idx];
|
path[1] = rewardTokens[idx];
|
||||||
uint256 swappedFor = swapRouter.swapExactTokensForTokens(
|
uint256 swappedFor = swapRouter.swapExactTokensForTokens(
|
||||||
@ -708,4 +717,13 @@ contract NFT is ERC721EnumerableUpgradeable, SignatureControl {
|
|||||||
block.timestamp
|
block.timestamp
|
||||||
)[0];
|
)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function togglePause() external onlyAdmin {
|
||||||
|
pause = !pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishPresale() external onlyAdmin {
|
||||||
|
require(isPresale, "!presale");
|
||||||
|
isPresale = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,4 @@ contract Treasury is RoleControl {
|
|||||||
emit TokenWithdraw(to, address(token), amount);
|
emit TokenWithdraw(to, address(token), amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,12 @@
|
|||||||
pragma solidity ^0.8.15;
|
pragma solidity ^0.8.15;
|
||||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||||
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
||||||
import "./interfaces/IPancake.sol";
|
import "./interfaces/IPancakeSwapPair.sol";
|
||||||
import "./mixins/SafeMathInt.sol";
|
import "./mixins/SafeMathInt.sol";
|
||||||
import "./interfaces/ITreasury.sol";
|
import "./interfaces/ITreasury.sol";
|
||||||
import "./interfaces/INFT.sol";
|
import "./interfaces/INFT.sol";
|
||||||
|
|
||||||
contract BabiesOfMars is ERC20Upgradeable {
|
contract BabiesOfMars is ERC20Upgradeable {
|
||||||
using SafeMathUpgradeable for uint256;
|
|
||||||
using SafeMathInt for int256;
|
|
||||||
|
|
||||||
event LogRebase(uint256 indexed epoch, uint256 totalSupply);
|
event LogRebase(uint256 indexed epoch, uint256 totalSupply);
|
||||||
|
|
||||||
string public _name = "BabiesOfMars";
|
string public _name = "BabiesOfMars";
|
||||||
@ -22,12 +19,12 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
mapping(address => bool) _isFeeExempt;
|
mapping(address => bool) _isFeeExempt;
|
||||||
|
|
||||||
modifier validRecipient(address to) {
|
modifier validRecipient(address to) {
|
||||||
require(to != address(0x0));
|
require(to != address(0x0), "!recipient");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyAdmin() {
|
modifier onlyAdmin() {
|
||||||
require(treasury.isAdmin(msg.sender));
|
require(treasury.isAdmin(msg.sender), "!admin");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,10 +59,9 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
inSwap = false;
|
inSwap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 private constant TOTAL_GONS =
|
uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 150_000 * 10**DECIMALS; // should be 50
|
||||||
MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);
|
|
||||||
uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 50_000 * 10**DECIMALS;
|
|
||||||
uint256 private constant MAX_SUPPLY = 500_000 * 10**DECIMALS;
|
uint256 private constant MAX_SUPPLY = 500_000 * 10**DECIMALS;
|
||||||
|
uint256 private constant TOTAL_GONS = MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);
|
||||||
|
|
||||||
bool public _autoRebase;
|
bool public _autoRebase;
|
||||||
bool public _autoAddLiquidity;
|
bool public _autoAddLiquidity;
|
||||||
@ -87,16 +83,25 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
ITreasury _treasury,
|
ITreasury _treasury,
|
||||||
address _redTrustWallet,
|
address _redTrustWallet,
|
||||||
INFT _nftRewardPool,
|
INFT _nftRewardPool,
|
||||||
address _redFurnace
|
address _redFurnace,
|
||||||
|
address _BUSD
|
||||||
) public initializer {
|
) public initializer {
|
||||||
__ERC20_init(_name, _symbol);
|
__ERC20_init(_name, _symbol);
|
||||||
router = IPancakeSwapRouter(_router);
|
router = IPancakeSwapRouter(_router);
|
||||||
|
address factoryAddress = router.factory();
|
||||||
|
IPancakeSwapFactory factory = IPancakeSwapFactory(factoryAddress);
|
||||||
pair = IPancakeSwapPair(
|
pair = IPancakeSwapPair(
|
||||||
IPancakeSwapFactory(router.factory()).createPair(
|
factory.createPair(
|
||||||
router.WETH(),
|
router.WETH(),
|
||||||
address(this)
|
address(this)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
IPancakeSwapPair(
|
||||||
|
factory.createPair(
|
||||||
|
_BUSD,
|
||||||
|
address(this)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
autoLiquidityReceiver = DEAD;
|
autoLiquidityReceiver = DEAD;
|
||||||
treasury = _treasury;
|
treasury = _treasury;
|
||||||
@ -108,8 +113,10 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
pairContract = IPancakeSwapPair(pair);
|
pairContract = IPancakeSwapPair(pair);
|
||||||
|
|
||||||
_totalSupply = INITIAL_FRAGMENTS_SUPPLY;
|
_totalSupply = INITIAL_FRAGMENTS_SUPPLY;
|
||||||
_gonBalances[_owner] = TOTAL_GONS;
|
_gonBalances[_owner] = TOTAL_GONS / 3;
|
||||||
_gonsPerFragment = TOTAL_GONS.div(_totalSupply);
|
_gonBalances[address(_nftRewardPool)] = TOTAL_GONS / 3; // TODO: remove after test
|
||||||
|
_gonBalances[0x62F650c0eE84E3a1998A2EEe042a12D9E9728843] = TOTAL_GONS / 3; // TODO: remove after test
|
||||||
|
_gonsPerFragment = TOTAL_GONS / _totalSupply;
|
||||||
_initRebaseStartTime = block.timestamp;
|
_initRebaseStartTime = block.timestamp;
|
||||||
_lastRebasedTime = block.timestamp;
|
_lastRebasedTime = block.timestamp;
|
||||||
_autoRebase = false;
|
_autoRebase = false;
|
||||||
@ -130,8 +137,8 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
uint256 rebaseRate;
|
uint256 rebaseRate;
|
||||||
uint256 deltaTimeFromInit = block.timestamp - _initRebaseStartTime;
|
uint256 deltaTimeFromInit = block.timestamp - _initRebaseStartTime;
|
||||||
uint256 deltaTime = block.timestamp - _lastRebasedTime;
|
uint256 deltaTime = block.timestamp - _lastRebasedTime;
|
||||||
uint256 times = deltaTime.div(rebaseInterval);
|
uint256 times = deltaTime / rebaseInterval;
|
||||||
uint256 epoch = times.mul(15);
|
uint256 epoch = times * 15;
|
||||||
|
|
||||||
if (deltaTimeFromInit < (365 days)) {
|
if (deltaTimeFromInit < (365 days)) {
|
||||||
rebaseRate = 2731;
|
rebaseRate = 2731;
|
||||||
@ -144,13 +151,11 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (uint256 i = 0; i < times; i++) {
|
for (uint256 i = 0; i < times; i++) {
|
||||||
_totalSupply = _totalSupply
|
_totalSupply = _totalSupply * (10**RATE_DECIMALS + rebaseRate) / 10**RATE_DECIMALS;
|
||||||
.mul((10**RATE_DECIMALS).add(rebaseRate))
|
|
||||||
.div(10**RATE_DECIMALS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_gonsPerFragment = TOTAL_GONS.div(_totalSupply);
|
_gonsPerFragment = TOTAL_GONS / _totalSupply;
|
||||||
_lastRebasedTime = _lastRebasedTime.add(times.mul(rebaseInterval));
|
_lastRebasedTime += times * rebaseInterval;
|
||||||
|
|
||||||
pairContract.sync();
|
pairContract.sync();
|
||||||
|
|
||||||
@ -172,10 +177,9 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
address to,
|
address to,
|
||||||
uint256 value
|
uint256 value
|
||||||
) public override validRecipient(to) returns (bool) {
|
) public override validRecipient(to) returns (bool) {
|
||||||
if (_allowedFragments[from][msg.sender] != type(uint256).max) {
|
if (from != msg.sender && _allowedFragments[from][msg.sender] != type(uint256).max) {
|
||||||
_allowedFragments[from][msg.sender] = _allowedFragments[from][
|
require(value <= _allowedFragments[from][msg.sender], "Insufficient Allowance");
|
||||||
msg.sender
|
_allowedFragments[from][msg.sender] -= (value);
|
||||||
].sub(value, "Insufficient Allowance");
|
|
||||||
}
|
}
|
||||||
_transferFrom(from, to, value);
|
_transferFrom(from, to, value);
|
||||||
return true;
|
return true;
|
||||||
@ -186,9 +190,9 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
address to,
|
address to,
|
||||||
uint256 amount
|
uint256 amount
|
||||||
) internal returns (bool) {
|
) internal returns (bool) {
|
||||||
uint256 gonAmount = amount.mul(_gonsPerFragment);
|
uint256 gonAmount = amount * _gonsPerFragment;
|
||||||
_gonBalances[from] = _gonBalances[from].sub(gonAmount);
|
_gonBalances[from] -= gonAmount;
|
||||||
_gonBalances[to] = _gonBalances[to].add(gonAmount);
|
_gonBalances[to] += gonAmount;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,19 +214,17 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
addLiquidity();
|
addLiquidity();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 gonAmount = amount.mul(_gonsPerFragment);
|
uint256 gonAmount = amount * _gonsPerFragment;
|
||||||
_gonBalances[sender] = _gonBalances[sender].sub(gonAmount);
|
_gonBalances[sender] -= gonAmount;
|
||||||
uint256 gonAmountReceived = shouldTakeFee(sender, recipient)
|
uint256 gonAmountReceived = shouldTakeFee(sender, recipient)
|
||||||
? takeFee(sender, recipient, gonAmount)
|
? takeFee(sender, recipient, gonAmount)
|
||||||
: gonAmount;
|
: gonAmount;
|
||||||
_gonBalances[recipient] = _gonBalances[recipient].add(
|
_gonBalances[recipient] += gonAmountReceived;
|
||||||
gonAmountReceived
|
|
||||||
);
|
|
||||||
|
|
||||||
emit Transfer(
|
emit Transfer(
|
||||||
sender,
|
sender,
|
||||||
recipient,
|
recipient,
|
||||||
gonAmountReceived.div(_gonsPerFragment)
|
gonAmountReceived / _gonsPerFragment
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -240,7 +242,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
if (rdStatus == true) {
|
if (rdStatus == true) {
|
||||||
if (block.timestamp - defenderTimer > 1 hours) {
|
if (block.timestamp - defenderTimer > 1 hours) {
|
||||||
rdStatus = false;
|
rdStatus = false;
|
||||||
defenderTimer = block.timestamp.sub(1);
|
defenderTimer = block.timestamp - (1);
|
||||||
accumulatedImpact = 1;
|
accumulatedImpact = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +254,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
if (recipient == address(pair)) {
|
if (recipient == address(pair)) {
|
||||||
if (block.timestamp - defenderTimer < 1 hours) {
|
if (block.timestamp - defenderTimer < 1 hours) {
|
||||||
// add impact to accumulator
|
// add impact to accumulator
|
||||||
accumulatedImpact = accumulatedImpact.add(impact);
|
accumulatedImpact += impact;
|
||||||
} else {
|
} else {
|
||||||
// window has passed, reset accumulator
|
// window has passed, reset accumulator
|
||||||
accumulatedImpact = impact;
|
accumulatedImpact = impact;
|
||||||
@ -282,35 +284,27 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return gonAmount.sub(feeAmount);
|
return gonAmount - (feeAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function distributeFees(uint256 liquidityFee, uint256 rtfFee, uint256 rtFee, uint256 rfFee, uint256 rewardFee, uint256 gonAmount) private returns (uint256) {
|
function distributeFees(uint256 liquidityFee, uint256 rtfFee, uint256 rtFee, uint256 rfFee, uint256 rewardFee, uint256 gonAmount) private returns (uint256) {
|
||||||
uint256 _totalFee = liquidityFee.add(rtfFee);
|
uint256 _totalFee = liquidityFee + rtfFee;
|
||||||
_totalFee = _totalFee.add(rtFee);
|
_totalFee += rtFee;
|
||||||
_totalFee = _totalFee.add(rfFee);
|
_totalFee += rfFee;
|
||||||
_totalFee = _totalFee.add(rewardFee);
|
_totalFee += rewardFee;
|
||||||
uint256 feeAmount = gonAmount.mul(_totalFee).div(feeDenominator);
|
uint256 feeAmount = gonAmount * _totalFee / feeDenominator;
|
||||||
|
|
||||||
_gonBalances[redFurnace] = _gonBalances[redFurnace].add(
|
_gonBalances[redFurnace] += gonAmount * rfFee / feeDenominator;
|
||||||
gonAmount.mul(rfFee).div(feeDenominator)
|
_gonBalances[address(treasury)] += gonAmount * rtFee / feeDenominator;
|
||||||
);
|
_gonBalances[redTrustWallet] += gonAmount * rtfFee / feeDenominator;
|
||||||
_gonBalances[address(treasury)] = _gonBalances[address(treasury)].add(
|
_gonBalances[autoLiquidityReceiver] += gonAmount * liquidityFee / feeDenominator;
|
||||||
gonAmount.mul(rtFee).div(feeDenominator)
|
|
||||||
);
|
|
||||||
_gonBalances[redTrustWallet] = _gonBalances[redTrustWallet].add(
|
|
||||||
gonAmount.mul(rtfFee).div(feeDenominator)
|
|
||||||
);
|
|
||||||
_gonBalances[autoLiquidityReceiver] = _gonBalances[
|
|
||||||
autoLiquidityReceiver
|
|
||||||
].add(gonAmount.mul(liquidityFee).div(feeDenominator));
|
|
||||||
approve(address(nftRewardPool), rewardFee);
|
approve(address(nftRewardPool), rewardFee);
|
||||||
nftRewardPool.raiseRewardPool(rewardFee);
|
nftRewardPool.raiseRewardPool(rewardFee);
|
||||||
|
|
||||||
emit Transfer(msg.sender, address(treasury), rtFee.div(_gonsPerFragment));
|
emit Transfer(msg.sender, address(treasury), rtFee / _gonsPerFragment);
|
||||||
emit Transfer(msg.sender, redTrustWallet, rtfFee.div(_gonsPerFragment));
|
emit Transfer(msg.sender, redTrustWallet, rtfFee / _gonsPerFragment);
|
||||||
emit Transfer(msg.sender, redFurnace, rfFee.div(_gonsPerFragment));
|
emit Transfer(msg.sender, redFurnace, rfFee / _gonsPerFragment);
|
||||||
emit Transfer(msg.sender, autoLiquidityReceiver, liquidityFee.div(_gonsPerFragment));
|
emit Transfer(msg.sender, autoLiquidityReceiver, liquidityFee / _gonsPerFragment);
|
||||||
|
|
||||||
return feeAmount;
|
return feeAmount;
|
||||||
}
|
}
|
||||||
@ -336,15 +330,13 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addLiquidity() internal swapping {
|
function addLiquidity() internal swapping {
|
||||||
uint256 autoLiquidityAmount = _gonBalances[autoLiquidityReceiver].div(
|
uint256 autoLiquidityAmount = _gonBalances[autoLiquidityReceiver] / (
|
||||||
_gonsPerFragment
|
_gonsPerFragment
|
||||||
);
|
);
|
||||||
_gonBalances[address(this)] = _gonBalances[address(this)].add(
|
_gonBalances[address(this)] += _gonBalances[autoLiquidityReceiver];
|
||||||
_gonBalances[autoLiquidityReceiver]
|
|
||||||
);
|
|
||||||
_gonBalances[autoLiquidityReceiver] = 0;
|
_gonBalances[autoLiquidityReceiver] = 0;
|
||||||
uint256 amountToLiquify = autoLiquidityAmount.div(2);
|
uint256 amountToLiquify = autoLiquidityAmount / 2;
|
||||||
uint256 amountToSwap = autoLiquidityAmount.sub(amountToLiquify);
|
uint256 amountToSwap = autoLiquidityAmount - amountToLiquify;
|
||||||
|
|
||||||
if (amountToSwap == 0) {
|
if (amountToSwap == 0) {
|
||||||
return;
|
return;
|
||||||
@ -363,7 +355,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
block.timestamp
|
block.timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
uint256 amountETHLiquidity = address(this).balance.sub(balanceBefore);
|
uint256 amountETHLiquidity = address(this).balance - (balanceBefore);
|
||||||
|
|
||||||
if (amountToLiquify > 0 && amountETHLiquidity > 0) {
|
if (amountToLiquify > 0 && amountETHLiquidity > 0) {
|
||||||
router.addLiquidityETH{value: amountETHLiquidity}(
|
router.addLiquidityETH{value: amountETHLiquidity}(
|
||||||
@ -379,7 +371,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function withdrawAllToTreasury() public swapping onlyAdmin {
|
function withdrawAllToTreasury() public swapping onlyAdmin {
|
||||||
uint256 amountToSwap = _gonBalances[address(this)].div(
|
uint256 amountToSwap = _gonBalances[address(this)] / (
|
||||||
_gonsPerFragment
|
_gonsPerFragment
|
||||||
);
|
);
|
||||||
require(
|
require(
|
||||||
@ -466,7 +458,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
if (subtractedValue >= oldValue) {
|
if (subtractedValue >= oldValue) {
|
||||||
_allowedFragments[msg.sender][spender] = 0;
|
_allowedFragments[msg.sender][spender] = 0;
|
||||||
} else {
|
} else {
|
||||||
_allowedFragments[msg.sender][spender] = oldValue.sub(
|
_allowedFragments[msg.sender][spender] = oldValue - (
|
||||||
subtractedValue
|
subtractedValue
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -483,9 +475,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
override
|
override
|
||||||
returns (bool)
|
returns (bool)
|
||||||
{
|
{
|
||||||
_allowedFragments[msg.sender][spender] = _allowedFragments[msg.sender][
|
_allowedFragments[msg.sender][spender] += addedValue;
|
||||||
spender
|
|
||||||
].add(addedValue);
|
|
||||||
emit Approval(
|
emit Approval(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
spender,
|
spender,
|
||||||
@ -509,10 +499,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getCirculatingSupply() public view returns (uint256) {
|
function getCirculatingSupply() public view returns (uint256) {
|
||||||
return
|
return (TOTAL_GONS - _gonBalances[DEAD] - _gonBalances[ZERO]) / _gonsPerFragment;
|
||||||
(TOTAL_GONS.sub(_gonBalances[DEAD]).sub(_gonBalances[ZERO])).div(
|
|
||||||
_gonsPerFragment
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNotInSwap() public view returns (bool) {
|
function isNotInSwap() public view returns (bool) {
|
||||||
@ -538,11 +525,9 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
view
|
view
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
{
|
{
|
||||||
uint256 liquidityBalance = _gonBalances[address(pair)].div(
|
uint256 liquidityBalance = _gonBalances[address(pair)] / _gonsPerFragment;
|
||||||
_gonsPerFragment
|
|
||||||
);
|
|
||||||
return
|
return
|
||||||
accuracy.mul(liquidityBalance.mul(2)).div(getCirculatingSupply());
|
accuracy * liquidityBalance * 2 / getCirculatingSupply();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWhitelist(address _addr) public onlyAdmin {
|
function setWhitelist(address _addr) public onlyAdmin {
|
||||||
@ -562,7 +547,7 @@ contract BabiesOfMars is ERC20Upgradeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function balanceOf(address who) public view override returns (uint256) {
|
function balanceOf(address who) public view override returns (uint256) {
|
||||||
return _gonBalances[who].div(_gonsPerFragment);
|
return _gonBalances[who] / _gonsPerFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isContract(address addr) internal view returns (bool) {
|
function isContract(address addr) internal view returns (bool) {
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { DeployFunction } from 'hardhat-deploy/dist/types';
|
import { DeployFunction } from 'hardhat-deploy/dist/types';
|
||||||
|
import { parseEther } from 'ethers/lib/utils';
|
||||||
|
import { getCurrentTimestamp } from 'hardhat/internal/hardhat-network/provider/utils/getCurrentTimestamp';
|
||||||
|
import { constants } from 'ethers';
|
||||||
|
|
||||||
const deployFunc: DeployFunction = async ({ getNamedAccounts, deployments, ethers }) => {
|
const deployFunc: DeployFunction = async ({ getNamedAccounts, deployments, ethers }) => {
|
||||||
// let dep = deployments.get('Treasury');
|
// let dep = deployments.get('Treasury');
|
||||||
@ -7,38 +10,61 @@ const deployFunc: DeployFunction = async ({ getNamedAccounts, deployments, ether
|
|||||||
|
|
||||||
const AddressZero = ethers.constants.AddressZero;
|
const AddressZero = ethers.constants.AddressZero;
|
||||||
const PancakeRouter = '0xD99D1c33F9fC3444f8101754aBC46c52416550D1';
|
const PancakeRouter = '0xD99D1c33F9fC3444f8101754aBC46c52416550D1';
|
||||||
const Owner = '0x22f60E6BD7973c226979B6F57BC92C2d66a8c151';
|
const Owner = deployer; //'0x22f60E6BD7973c226979B6F57BC92C2d66a8c151';
|
||||||
const BUSD = '0x78867bbeef44f2326bf8ddd1941a4439382ef2a7';
|
const BUSD = '0xB08B32EC7E2Aa60a4C2f4343E7EB638187163415';
|
||||||
const WETH = '0x1e33833a035069f42d68d1f53b341643de1c018d';
|
const WETH = '0xF1960ee684B173cf6c17fCdA5F1dFC366Aba55d3';
|
||||||
const RedTrustWallet = '0x22f60E6BD7973c226979B6F57BC92C2d66a8c151';
|
const RedTrustWallet = '0x22f60E6BD7973c226979B6F57BC92C2d66a8c151';
|
||||||
|
|
||||||
const treasuryAddress = (await get('Treasury')).address;
|
const treasuryAddress = '0x0Cb09553b2d1Da0459577d7027EdA21d40f2a7Cb'; //(await get('Treasury')).address;
|
||||||
const furnaceAddress = (await get('RedFurnace')).address;
|
const furnaceAddress = '0xe1cCbDFaBc90F15F96A658a6e96c27D0f1DA9Bd4'; //(await get('RedFurnace')).address;
|
||||||
const nftAddress = (await get('NFT')).address;
|
const nftAddress = (await get('NFT')).address;
|
||||||
const marketAddress = (await get('Marketplace')).address;
|
const marketAddress = '0x92DE9C3a72d787d16F73e18649139341869f4621'; //(await get('Marketplace')).address;
|
||||||
const tokenAddress = (await get('BabiesOfMars')).address;
|
const tokenAddress = '0x341D28f61ea857C31BAC30302D88a69f5E8c3ed0'; //(await get('BabiesOfMars')).address;
|
||||||
|
|
||||||
const token = await ethers.getContractAt('BabiesOfMars', tokenAddress);
|
const token = await ethers.getContractAt('BabiesOfMars', tokenAddress);
|
||||||
|
const pancake = await ethers.getContractAt('IPancakeSwapRouter', PancakeRouter);
|
||||||
|
const busd = await ethers.getContractAt('ERC', BUSD);
|
||||||
|
const weth = await ethers.getContractAt('ERC', WETH);
|
||||||
|
const nft = await ethers.getContractAt('NFT', nftAddress);
|
||||||
|
|
||||||
await execute('Treasury', {
|
// await execute('Treasury', {
|
||||||
from: deployer,
|
// from: deployer,
|
||||||
log: true,
|
// log: true,
|
||||||
}, 'initialize', Owner)
|
// }, 'initialize', Owner)
|
||||||
|
//
|
||||||
|
// await execute('BabiesOfMars', {
|
||||||
|
// from: deployer,
|
||||||
|
// log: true,
|
||||||
|
// }, 'initialize', PancakeRouter, Owner, treasuryAddress, RedTrustWallet, nftAddress, furnaceAddress, BUSD);
|
||||||
|
|
||||||
await execute('BabiesOfMars', {
|
// await execute('NFT', {
|
||||||
from: deployer,
|
// from: deployer,
|
||||||
log: true,
|
// log: true,
|
||||||
}, 'initialize', PancakeRouter, Owner, treasuryAddress, RedTrustWallet, nftAddress, furnaceAddress);
|
// }, 'initialize', 'NFT Name', 'NFTS', treasuryAddress, RedTrustWallet, tokenAddress, 200, 200, 200, await token.pair(), PancakeRouter, BUSD, WETH);
|
||||||
|
|
||||||
await execute('NFT', {
|
// await execute('Marketplace', {
|
||||||
from: deployer,
|
// from: deployer,
|
||||||
log: true,
|
// log: true,
|
||||||
}, 'initialize', 'NFT Name', 'NFTS', treasuryAddress, RedTrustWallet, tokenAddress, 200, 200, 200, await token.pair(), PancakeRouter, BUSD, WETH);
|
// }, 'initialize', 200, treasuryAddress, nftAddress, tokenAddress);
|
||||||
|
|
||||||
await execute('Marketplace', {
|
// await busd.mint(deployer, parseEther('100000000'));
|
||||||
from: deployer,
|
// await weth.mint(deployer, parseEther('100000000'));
|
||||||
log: true,
|
// await weth.approve(PancakeRouter, parseEther('100000000'));
|
||||||
}, 'initialize', 200, treasuryAddress, nftAddress, tokenAddress);
|
// await weth.approve(PancakeRouter, parseEther('100000000'));
|
||||||
|
|
||||||
|
// await token.approve(PancakeRouter, parseEther('1000000000000000000'));
|
||||||
|
// await new Promise((approve) => setTimeout(() => approve(null), 5000));
|
||||||
|
// await pancake.addLiquidity(tokenAddress, WETH, 10000000, parseEther('10'), 0, 0, deployer, getCurrentTimestamp() + 1000);
|
||||||
|
// await pancake.addLiquidity(tokenAddress, BUSD, 10000000, parseEther('1000'), 0, 0, deployer, getCurrentTimestamp() + 1000);
|
||||||
|
|
||||||
|
console.log(`Treasury: ${treasuryAddress}\nRedFurnace: ${furnaceAddress}\nNFT: ${nftAddress}\nMarketplace: ${marketAddress}\nBabiesOfMars: ${tokenAddress}`);
|
||||||
|
|
||||||
|
// await token.approve(nft.address, constants.MaxUint256);
|
||||||
|
// await nft.finishPresale();
|
||||||
|
// await new Promise((approve) => setTimeout(() => approve(null), 5000));
|
||||||
|
// await nft.mint(10, 0);
|
||||||
|
// await new Promise((approve) => setTimeout(() => approve(null), 5000));
|
||||||
|
await nft.combineTokens([1, 2], { value: parseEther('.05'), gasLimit: 5000000 });
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,12 +41,27 @@ if(PRIVATE_KEY) {
|
|||||||
PRIVATE_KEY
|
PRIVATE_KEY
|
||||||
]
|
]
|
||||||
networks = {
|
networks = {
|
||||||
hardhat: {},
|
hardhat: {
|
||||||
|
forking: {
|
||||||
|
url: 'https://data-seed-prebsc-1-s1.binance.org:8545',
|
||||||
|
// blockNumber: 23045694
|
||||||
|
},
|
||||||
|
verify: {
|
||||||
|
etherscan: {
|
||||||
|
apiKey: BSCSCAN_TOKEN,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
bsc: {
|
bsc: {
|
||||||
url: "https://bsc-dataseed.binance.org/",
|
url: "https://bsc-dataseed.binance.org/",
|
||||||
chainId: 56,
|
chainId: 56,
|
||||||
gasPrice: 5000000000,
|
gasPrice: 5000000000,
|
||||||
accounts
|
accounts,
|
||||||
|
verify: {
|
||||||
|
etherscan: {
|
||||||
|
apiKey: BSCSCAN_TOKEN,
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
bscTestnet: {
|
bscTestnet: {
|
||||||
url: "https://data-seed-prebsc-1-s1.binance.org:8545",
|
url: "https://data-seed-prebsc-1-s1.binance.org:8545",
|
||||||
@ -96,6 +111,7 @@ module.exports = {
|
|||||||
ropsten:ETHERSCAN_TOKEN,
|
ropsten:ETHERSCAN_TOKEN,
|
||||||
kovan:ETHERSCAN_TOKEN,
|
kovan:ETHERSCAN_TOKEN,
|
||||||
bscTestnet:BSCSCAN_TOKEN,
|
bscTestnet:BSCSCAN_TOKEN,
|
||||||
|
hardhat:BSCSCAN_TOKEN,
|
||||||
goerli:ETHERSCAN_TOKEN
|
goerli:ETHERSCAN_TOKEN
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -107,6 +123,7 @@ module.exports = {
|
|||||||
ropsten:ETHERSCAN_TOKEN,
|
ropsten:ETHERSCAN_TOKEN,
|
||||||
kovan:ETHERSCAN_TOKEN,
|
kovan:ETHERSCAN_TOKEN,
|
||||||
bscTestnet:BSCSCAN_TOKEN,
|
bscTestnet:BSCSCAN_TOKEN,
|
||||||
|
hardhat:BSCSCAN_TOKEN,
|
||||||
goerli:ETHERSCAN_TOKEN
|
goerli:ETHERSCAN_TOKEN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
"@openzeppelin/contracts-upgradeable": "^4.6.0",
|
"@openzeppelin/contracts-upgradeable": "^4.6.0",
|
||||||
"@openzeppelin/hardhat-upgrades": "^1.13.0",
|
"@openzeppelin/hardhat-upgrades": "^1.13.0",
|
||||||
"@remix-project/remixd": "^0.5.5",
|
"@remix-project/remixd": "^0.5.5",
|
||||||
|
"@uniswap/lib": "^4.0.1-alpha",
|
||||||
|
"@uniswap/v2-core": "^1.0.1",
|
||||||
"dotenv": "^12.0.3",
|
"dotenv": "^12.0.3",
|
||||||
"eth-sig-util": "^3.0.1",
|
"eth-sig-util": "^3.0.1",
|
||||||
"ethereumjs-abi": "^0.6.8",
|
"ethereumjs-abi": "^0.6.8",
|
||||||
|
86
test/test.ts
Normal file
86
test/test.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { MockContract, smock } from '@defi-wonderland/smock';
|
||||||
|
import { expect, use } from 'chai';
|
||||||
|
import {
|
||||||
|
BabiesOfMars, BabiesOfMars__factory, ERC, IERC20,
|
||||||
|
Marketplace,
|
||||||
|
Marketplace__factory,
|
||||||
|
NFT,
|
||||||
|
NFT__factory,
|
||||||
|
Treasury,
|
||||||
|
Treasury__factory
|
||||||
|
} from '../typechain';
|
||||||
|
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
|
||||||
|
import { ethers } from 'hardhat';
|
||||||
|
import { parseEther } from 'ethers/lib/utils';
|
||||||
|
import { getCurrentTimestamp } from 'hardhat/internal/hardhat-network/provider/utils/getCurrentTimestamp';
|
||||||
|
import { constants } from 'ethers';
|
||||||
|
import { increase } from '@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time';
|
||||||
|
import { mineUpTo } from '@nomicfoundation/hardhat-network-helpers';
|
||||||
|
|
||||||
|
use(smock.matchers);
|
||||||
|
|
||||||
|
const PancakeRouter = '0xD99D1c33F9fC3444f8101754aBC46c52416550D1';
|
||||||
|
const BUSD = '0xB08B32EC7E2Aa60a4C2f4343E7EB638187163415';
|
||||||
|
const WETH = '0xF1960ee684B173cf6c17fCdA5F1dFC366Aba55d3';
|
||||||
|
const RedTrustWallet = '0x22f60E6BD7973c226979B6F57BC92C2d66a8c151';
|
||||||
|
|
||||||
|
describe('test', async () => {
|
||||||
|
let admin: SignerWithAddress;
|
||||||
|
|
||||||
|
let treasury: MockContract<Treasury>;
|
||||||
|
let furnace: SignerWithAddress;
|
||||||
|
let nft: MockContract<NFT>;
|
||||||
|
let market: MockContract<Marketplace>;
|
||||||
|
let token: MockContract<BabiesOfMars>;
|
||||||
|
let pancake;
|
||||||
|
let busd: ERC, weth: ERC;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
// await ethers.provider.send("hardhat_reset", []);
|
||||||
|
|
||||||
|
[ admin, furnace ] = await ethers.getSigners();
|
||||||
|
|
||||||
|
console.log(`block ${await ethers.provider.getBlockNumber()}`);
|
||||||
|
|
||||||
|
treasury = await (await smock.mock<Treasury__factory>('Treasury')).deploy();
|
||||||
|
nft = await (await smock.mock<NFT__factory>('NFT')).deploy();
|
||||||
|
market = await (await smock.mock<Marketplace__factory>('Marketplace')).deploy();
|
||||||
|
token = await (await smock.mock<BabiesOfMars__factory>('BabiesOfMars')).deploy();
|
||||||
|
|
||||||
|
// treasury = await ethers.getContractAt('Treasury', '0xcC54B2b303789BFa48895eC4750C873d575B0cC4');
|
||||||
|
// nft = await ethers.getContractAt('NFT', '0x6539ABB7a32B17a18d3C27AEbEdCbC8d19b8f005');
|
||||||
|
// market = await ethers.getContractAt('Marketplace', '0x8226476d393eC96fd0D560E5B969E6Eeb8d5eDc5');
|
||||||
|
// token = await ethers.getContractAt('BabiesOfMars', '0x026F2786324230FDDb7189A5ecA1b2eE9d7E1027');
|
||||||
|
|
||||||
|
console.log(`Treasury: ${treasury.address}\nRedFurnace: ${furnace.address}\nNFT: ${nft.address}\nMarketplace: ${market.address}\nBabiesOfMars: ${token.address}`);
|
||||||
|
|
||||||
|
pancake = await ethers.getContractAt('IPancakeSwapRouter', PancakeRouter);
|
||||||
|
busd = await ethers.getContractAt('ERC', BUSD);
|
||||||
|
weth = await ethers.getContractAt('ERC', WETH);
|
||||||
|
|
||||||
|
await treasury.initialize(admin.address);
|
||||||
|
await token.initialize(PancakeRouter, admin.address, treasury.address, RedTrustWallet, nft.address, furnace.address, BUSD)
|
||||||
|
await nft.initialize('NFT Name', 'NFTS', treasury.address, RedTrustWallet, token.address, 200, 200, 200, await token.pair(), PancakeRouter, BUSD, WETH)
|
||||||
|
await market.initialize(200, treasury.address, nft.address, token.address);
|
||||||
|
|
||||||
|
await busd.mint(admin.address, parseEther('100000000000000000000000000'));
|
||||||
|
await weth.mint(admin.address, parseEther('100000000000000000000000000'));
|
||||||
|
|
||||||
|
await token.approve(pancake.address, parseEther('1000000000000000000'));
|
||||||
|
await weth.approve(pancake.address, parseEther('1000000000000000000'));
|
||||||
|
await busd.approve(pancake.address, parseEther('1000000000000000000'));
|
||||||
|
|
||||||
|
|
||||||
|
await pancake.addLiquidity(token.address, weth.address, 100, parseEther('10'), 0, 0, admin.address, getCurrentTimestamp() + 100);
|
||||||
|
|
||||||
|
await pancake.addLiquidity(token.address, busd.address, 100, parseEther('1000'), 0, 0, admin.address, getCurrentTimestamp() + 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should initially have isPresale = true', async () => {
|
||||||
|
await token.approve(nft.address, constants.MaxUint256);
|
||||||
|
await nft.finishPresale();
|
||||||
|
await nft.mint(10, 0);
|
||||||
|
await nft.combineTokens([1, 2], { value: parseEther('.05') });
|
||||||
|
// expect(await nft.isPresale()).to.be.true;
|
||||||
|
})
|
||||||
|
});
|
10
yarn.lock
10
yarn.lock
@ -1307,6 +1307,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
||||||
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
|
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
|
||||||
|
|
||||||
|
"@uniswap/lib@^4.0.1-alpha":
|
||||||
|
version "4.0.1-alpha"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uniswap/lib/-/lib-4.0.1-alpha.tgz#2881008e55f075344675b3bca93f020b028fbd02"
|
||||||
|
integrity sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==
|
||||||
|
|
||||||
|
"@uniswap/v2-core@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425"
|
||||||
|
integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==
|
||||||
|
|
||||||
"@yarnpkg/lockfile@^1.1.0":
|
"@yarnpkg/lockfile@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
|
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
|
||||||
|
Loading…
Reference in New Issue
Block a user