publish Candy Badge, add TokenMall

This commit is contained in:
yuexin 2023-08-01 13:16:04 +08:00
parent cbc05128c8
commit 8dc226a3f3
12 changed files with 26726 additions and 5335 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -52,7 +52,8 @@
}
],
"stateMutability": "view",
"type": "function"
"type": "function",
"constant": true
},
{
"inputs": [],
@ -65,7 +66,8 @@
}
],
"stateMutability": "view",
"type": "function"
"type": "function",
"constant": true
},
{
"inputs": [],
@ -109,7 +111,8 @@
}
],
"stateMutability": "view",
"type": "function"
"type": "function",
"constant": true
},
{
"inputs": [
@ -10158,9 +10161,16 @@
"name": "solc",
"version": "0.8.10+commit.fc410830.Emscripten.clang"
},
"networks": {},
"networks": {
"42161": {
"links": {},
"address": "0xB628D151790Dde4A645469350089aCE8628e8Aa4",
"transactionHash": "0xd9f0ed9559f80965b184edccbabccd039aafdf6acbf2ae59b3950f71321e1df8",
"events": {}
}
},
"schemaVersion": "3.4.14",
"updatedAt": "2023-07-27T05:56:41.484Z",
"updatedAt": "2023-08-01T04:55:05.219Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -2603,7 +2603,7 @@
}
},
"schemaVersion": "3.4.14",
"updatedAt": "2023-07-27T09:02:33.945Z",
"updatedAt": "2023-08-01T04:55:05.238Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -20171,6 +20171,12 @@
"address": "0x59d3631c86BbE35EF041872d502F218A39FBa150",
"transactionHash": "0xffe662a1ca0c676eccc4d63c736fade4da8fe3e07cbd2d09ed027649655728e4"
},
"42161": {
"events": {},
"links": {},
"address": "0x41D79d900a0aD3017F4697FC19f9E2EE04D05F37",
"transactionHash": "0x00bced82d4ab96fe241a15fa641c91711936e12eaee0b09ab199c335da62ea1b"
},
"80001": {
"events": {
"0x044ffb6dcd4ec715d7d57b6c88fa43e63f1e156efb2a93d1072314f910286e9d": {
@ -20412,7 +20418,7 @@
}
},
"schemaVersion": "3.4.14",
"updatedAt": "2023-07-27T09:02:33.937Z",
"updatedAt": "2023-08-01T04:55:05.229Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -0,0 +1,109 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../utils/UInt.sol";
import "./MallBase.sol";
interface ICurrency is IERC20 {
function decimals() external view returns (uint256);
}
contract BETokenMall is MallBase, ReentrancyGuard {
using SafeERC20 for IERC20;
using UInt for uint256;
uint256 constant ROUND = 1000000;
address public tokenAddress;
address public seller;
// currency => price
mapping(address => uint256) public prices;
// Events
event BuyTransaction(
address indexed buyer,
address tokenAddress,
address currency,
uint256 amount,
uint256 tokenAmount
);
event TokenAddressUpdated(address tokenAddress);
event SellerUpdated(address seller);
event UpdateTokenPrice(address currency, uint256 price, uint256 pricePre);
/**
* @dev Constructor
*/
constructor(address _tokenAddress, address _seller) {
tokenAddress = _tokenAddress;
seller = _seller;
}
/**
* @dev Update token address
*/
function updateTokenAddress(address _tokenAddress) external onlyOwner {
tokenAddress = _tokenAddress;
emit TokenAddressUpdated(_tokenAddress);
}
/**
* @dev Update seller address
*/
function updateSeller(address _seller) external onlyOwner {
seller = _seller;
emit SellerUpdated(_seller);
}
/**
* @dev Update token price
*/
function updateTokenPrice(
address currency,
uint256 price
) external onlyOwner {
uint256 pricePre = prices[currency];
prices[currency] = price;
emit UpdateTokenPrice(currency, price, pricePre);
}
/**
* @dev Buy token
*/
function buyToken(address currency, uint256 amount) external nonReentrant {
require(amount > 0, "BETokenMall: invalid amount");
require(erc20Supported[currency], "BETokenMall: invalid payment method");
require(prices[currency] > 0, "BETokenMall: invalid token price");
// calc currency amount
uint256 currencyDecimal = ICurrency(currency).decimals();
uint256 tokenAmount = (prices[currency] *
amount *
(10 ** (18 - currencyDecimal))) / ROUND;
address buyer = _msgSender();
require(
IERC20(tokenAddress).balanceOf(seller) >= tokenAmount,
"BETokenMall: seller doesn't have enough token to sell this item"
);
require(
IERC20(tokenAddress).allowance(seller, address(this)) >= tokenAmount,
"BETokenMall: seller doesn't approve enough token to sell this item"
);
// Check payment approval and buyer balance
require(
IERC20(currency).balanceOf(buyer) >= amount,
"BETokenMall: buyer doesn't have enough token to buy this item"
);
require(
IERC20(currency).allowance(buyer, address(this)) >= amount,
"BETokenMall: buyer doesn't approve enough token to buy this item"
);
// Transfer payment to seller
IERC20(currency).safeTransferFrom(buyer, feeToAddress, amount);
// Transfer token to buyer
IERC20(tokenAddress).safeTransferFrom(seller, buyer, tokenAmount);
// emit buy event
emit BuyTransaction(buyer, tokenAddress, currency, amount, tokenAmount);
}
}

View File

@ -7,20 +7,20 @@ const Distributor = artifacts.require("logic/NftDistributor");
module.exports = async function (deployer, network, accounts) {
const name = "Candy";
const symbol = "CANDY";
await deployer.deploy(Box, name, symbol, 0);
// await deployer.deploy(Box, name, symbol, 0);
const gachaInstance = await Box.deployed();
if (gachaInstance) {
console.log("Candy successfully deployed.");
}
base.updateArray({
name: "Candy",
type: "erc721",
json: "assets/contracts/BEBadge.json",
address: gachaInstance.address,
network,
});
// base.updateArray({
// name: "Candy",
// type: "erc721",
// json: "assets/contracts/BEBadge.json",
// address: gachaInstance.address,
// network,
// });
const metaaddr = '0xfba1F2861718993B94edd5DCe1D06b3Cbe19353d'
let metaaddr = '0xfba1F2861718993B94edd5DCe1D06b3Cbe19353d'
if(network == 'arbitrum_one'){
// await deployer.deploy(Metadata);
@ -37,7 +37,8 @@ module.exports = async function (deployer, network, accounts) {
// });
const mtname = name
const mtdesc = "this is test badge desc."
const mtdesc = "Candy Badge are exclusive to new friends entering the world of CiunterFire,\\n\
it will have airdrop attributes and in-game benefits."
const mtimg = "https://gateway.pinata.cloud/ipfs/QmWuHBFGirZS7uyGDyEJNBnMjGLsP9Ke4QZaoL2MxYWtat"
const mtex = ',"animation_url": "https://gateway.pinata.cloud/ipfs/QmRJAN58RaFZUeor9VhdiqCziujwvwD98zq7xHUnmbzMXW"'
@ -60,7 +61,7 @@ module.exports = async function (deployer, network, accounts) {
const testexec = ['0x1cC73CE74BA0BC080e7C0a37cb3a68f435Ab333A']
const exec = network == 'arbitrum_one'? config.admins.executors: testexec
let exec = network == 'arbitrum_one'? config.admins.executors: testexec
console.log('exec addrs:', exec)

View File

@ -2,6 +2,9 @@ const BENftMarket = artifacts.require("market/BENftMarket");
const BENftMall = artifacts.require("market/BENftMall");
const GameItemMarket = artifacts.require("market/GameItemMarket");
const GameItemMall = artifacts.require("market/GameItemMall");
const FT = artifacts.require("tokens/erc20/FT");
const BETokenMall = artifacts.require("market/BETokenMall");
const config = require("../config/config");
const base = require("../scripts/base");
module.exports = async function (deployer, network, accounts) {
@ -18,16 +21,40 @@ module.exports = async function (deployer, network, accounts) {
// network,
// });
await deployer.deploy(BENftMall);
const nftMallInstance = await BENftMall.deployed();
if (nftMallInstance) {
console.log("BENftMall successfully deployed.");
// await deployer.deploy(BENftMall);
// const nftMallInstance = await BENftMall.deployed();
// if (nftMallInstance) {
// console.log("BENftMall successfully deployed.");
// }
// base.updateArray({
// name: "BENftMall",
// type: "logic",
// json: "assets/contracts/BENftMall.json",
// address: nftMallInstance.address,
// network,
// });
let cfgs = base.loadData({ network });
const cegInstance = await FT.at(cfgs.find((c) => c.name === "CEG").address);
await deployer.deploy(
BETokenMall,
cegInstance.address,
config.market.feeToAddress
);
const tokenMallInstance = await BETokenMall.deployed();
if (tokenMallInstance) {
console.log("BETokenMall successfully deployed.");
}
await tokenMallInstance.setFeeToAddress(config.market.feeToAddress);
const usdcInstance = await FT.at(
cfgs.find((c) => c.name === "BEUSDC").address
);
await tokenMallInstance.addERC20Support(usdcInstance.address);
await tokenMallInstance.updateTokenPrice(usdcInstance.address, "10000000");
base.updateArray({
name: "BENftMall",
name: "BETokenMall",
type: "logic",
json: "assets/contracts/BENftMall.json",
address: nftMallInstance.address,
json: "assets/contracts/BETokenMall.json",
address: tokenMallInstance.address,
network,
});

View File

@ -51,6 +51,7 @@ module.exports = async function (deployer, network, accounts) {
`success set mint role to: ${factoryInstance.address} claim box `
);
await factoryInstance.removeTokenSupport(gachaInstance.address);
// await factoryInstance.addTokenSupport(gachaInstance.address);
console.log(`success add token support to: ${gachaInstance.address}`);
@ -59,13 +60,13 @@ module.exports = async function (deployer, network, accounts) {
// await gachaInstance.updateMetaAddress(metadataInstance.address);
console.log(`success update meta address for: ${gachaInstance.address}`);
await metadataInstance.setMetaData(
gachaInstance.address,
"Gacha",
"The Gacha featuring the character 'Hill' from the game, as rewards for Quest missions before CounterFire's official launch.\\nCan get it by participating in the Quest, and it will have multiple benefits.\\nCounterFire is the highly-anticipated first blockchain-based game to offer a unique combination of MOBA and Battle Royale gameplay.Available on Google Play.\\n official website:CounterFire.games",
"https://gateway.pinata.cloud/ipfs/Qmdbki45yWsdCvWJmLkTDb2TRPM1Kxe3gDFr6q3xaBHxeF",
""
);
// await metadataInstance.setMetaData(
// gachaInstance.address,
// "Gacha",
// "The Gacha featuring the character 'Hill' from the game, as rewards for Quest missions before CounterFire's official launch.\\nCan get it by participating in the Quest, and it will have multiple benefits.\\nCounterFire is the highly-anticipated first blockchain-based game to offer a unique combination of MOBA and Battle Royale gameplay.Available on Google Play.\\n official website:CounterFire.games",
// "https://gateway.pinata.cloud/ipfs/Qmdbki45yWsdCvWJmLkTDb2TRPM1Kxe3gDFr6q3xaBHxeF",
// ""
// );
console.log(`success update metadata for: ${gachaInstance.address}`);
};

View File

@ -22,5 +22,17 @@
"type": "erc721",
"json": "assets/contracts/BEBadge.json",
"address": "0xD728de3d9ebeD90E84aBe84539280cbC5b18E304"
},
{
"name": "Candy",
"type": "erc721",
"json": "assets/contracts/BEBadge.json",
"address": "0xefD4c863E73e7E9Cc33d46fB30CE51510FCFdeb0"
},
{
"name": "NftDistributor",
"type": "logic",
"json": "assets/contracts/NftDistributor.json",
"address": "0x41D79d900a0aD3017F4697FC19f9E2EE04D05F37"
}
]

View File

@ -25,6 +25,7 @@
"genesis_deploy:test": "truffle migrate --network arbitrum_testnet -f 16 --to 16 --compile-none",
"mulwallet:one": "npx truffle exec --network arbitrum_one_self ./init_scripts/generate_mulwallet.js",
"candy_deploy:test": "truffle migrate --network arbitrum_testnet -f 17 --to 17 --compile-none",
"candy_deploy:one": "truffle migrate --network arbitrum_one -f 17 --to 17 --compile-none",
"size": "truffle run contract-size"
},
"author": "",