增加一个用于burn nft的合约

This commit is contained in:
CounterFire2023 2024-01-10 15:11:59 +08:00
parent 9258f7d464
commit 89efe5253f
16 changed files with 14135 additions and 103 deletions

View File

@ -38312,12 +38312,12 @@
} }
}, },
"links": {}, "links": {},
"address": "0xe2E4D5a4045fBFcbCBECAf5b8A94303712d2FA97", "address": "0x6a673D946a976776fd5F163d9d831b2fEB600015",
"transactionHash": "0x6cd38599ef7660f9dfc6416bfe10bc3208699d4ab0e96cdde7beee6984c6cc8c" "transactionHash": "0x891eca78035632e35ac8f5617089b7ed165c78a73deb43ac9d55e3a027925f91"
} }
}, },
"schemaVersion": "3.4.16", "schemaVersion": "3.4.16",
"updatedAt": "2023-12-27T06:07:59.193Z", "updatedAt": "2024-01-10T06:03:43.853Z",
"networkType": "ethereum", "networkType": "ethereum",
"devdoc": { "devdoc": {
"kind": "dev", "kind": "dev",

View File

@ -46453,7 +46453,7 @@
} }
}, },
"schemaVersion": "3.4.16", "schemaVersion": "3.4.16",
"updatedAt": "2023-12-27T05:51:26.136Z", "updatedAt": "2024-01-09T02:33:38.506Z",
"networkType": "ethereum", "networkType": "ethereum",
"devdoc": { "devdoc": {
"events": { "events": {

View File

@ -19455,7 +19455,7 @@
} }
}, },
"schemaVersion": "3.4.16", "schemaVersion": "3.4.16",
"updatedAt": "2023-12-27T05:51:26.126Z", "updatedAt": "2024-01-09T02:33:38.498Z",
"networkType": "ethereum", "networkType": "ethereum",
"devdoc": { "devdoc": {
"kind": "dev", "kind": "dev",

1966
build/contracts/IBadge.json Normal file

File diff suppressed because one or more lines are too long

1961
build/contracts/ISbt.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -3259,7 +3259,7 @@
} }
}, },
"schemaVersion": "3.4.16", "schemaVersion": "3.4.16",
"updatedAt": "2023-12-27T06:13:06.086Z", "updatedAt": "2024-01-10T06:03:43.872Z",
"networkType": "ethereum", "networkType": "ethereum",
"devdoc": { "devdoc": {
"kind": "dev", "kind": "dev",

View File

@ -33954,8 +33954,8 @@
} }
}, },
"links": {}, "links": {},
"address": "0x22Ac497e7FbdaDDB6945354F8080998f4Abbdc4b", "address": "0xFAA03824c38Ed5102F9F901987FA7cd9d193449B",
"transactionHash": "0xdb9d7f9179a623c585fa0db6692df385b2731f0c8d47d701dd2754e2ead6da8d" "transactionHash": "0x016bbf6f248a4fe8bcb7e8839bf0715e2f5a0316bf0a05754e4b6b768972bd9c"
}, },
"1665974821170": { "1665974821170": {
"events": {}, "events": {},
@ -33965,7 +33965,7 @@
} }
}, },
"schemaVersion": "3.4.16", "schemaVersion": "3.4.16",
"updatedAt": "2023-12-27T06:13:06.079Z", "updatedAt": "2024-01-10T04:48:11.625Z",
"networkType": "ethereum", "networkType": "ethereum",
"devdoc": { "devdoc": {
"kind": "dev", "kind": "dev",

View File

@ -183,7 +183,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [], "inputs": [],
@ -196,7 +197,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [], "inputs": [],
@ -209,7 +211,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -246,7 +249,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -265,7 +269,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -284,7 +289,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -326,7 +332,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -350,7 +357,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [], "inputs": [],
@ -363,7 +371,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [], "inputs": [],
@ -376,7 +385,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -395,7 +405,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -513,7 +524,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [], "inputs": [],
@ -526,7 +538,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -545,7 +558,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -569,7 +583,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [], "inputs": [],
@ -582,7 +597,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -624,7 +640,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -656,7 +673,8 @@
} }
], ],
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function",
"constant": true
}, },
{ {
"inputs": [ "inputs": [
@ -32837,9 +32855,168 @@
"name": "solc", "name": "solc",
"version": "0.8.10+commit.fc410830.Emscripten.clang" "version": "0.8.10+commit.fc410830.Emscripten.clang"
}, },
"networks": {}, "networks": {
"schemaVersion": "3.4.4", "421614": {
"updatedAt": "2023-12-01T09:03:16.832Z", "events": {
"0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": {
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "approved",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
"0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31": {
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
"0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff": {
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
"0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d": {
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
"0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b": {
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": {
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
}
},
"links": {},
"address": "0x7b6399DFbed8Bc46F6A498C6B1040E80c2B5C4bc",
"transactionHash": "0xe627bc394fc631866323113b35d587151e7defff1d80521525124a7969340d21"
}
},
"schemaVersion": "3.4.16",
"updatedAt": "2024-01-10T06:03:43.865Z",
"networkType": "ethereum",
"devdoc": { "devdoc": {
"kind": "dev", "kind": "dev",
"methods": { "methods": {

File diff suppressed because one or more lines are too long

View File

@ -25852,7 +25852,7 @@
} }
}, },
"schemaVersion": "3.4.16", "schemaVersion": "3.4.16",
"updatedAt": "2023-12-27T05:51:26.147Z", "updatedAt": "2024-01-09T02:33:38.519Z",
"networkType": "ethereum", "networkType": "ethereum",
"devdoc": { "devdoc": {
"kind": "dev", "kind": "dev",

View File

@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IBadge is IERC721{
function burn(address owner, uint256 tokenId) external;
}
interface ISbt is IERC721{
function burn(uint256 tokenId) external;
}
contract NftBuner is AccessControlEnumerable {
event BatchBurn(
address indexed user,
uint256 indexed tokenId,
address indexed nft,
uint256[] tokenIds
);
function brunBadge(address _badge, uint256[] calldata _nftIds) external {
address user = _msgSender();
for (uint256 i = 0; i < _nftIds.length; i++) {
IBadge(_badge).burn(user, _nftIds[i]);
}
emit BatchBurn(user, 0, _badge, _nftIds);
}
function burnSbt(address _nft, uint256[] calldata _nftIds) external{
for (uint256 i = 0; i < _nftIds.length; i++) {
ISbt(_nft).burn(_nftIds[i]);
}
address user = _msgSender();
emit BatchBurn(user, 0, _nft, _nftIds);
}
}

View File

@ -0,0 +1,34 @@
const base = require("../scripts/base");
const NftBuner = artifacts.require("logic/NftBuner");
const Badge = artifacts.require("tokens/erc721/BEBadge");
const NFTSbt = artifacts.require("tokens/erc721/NFTSbt");
module.exports = async function (deployer, network, accounts) {
await deployer.deploy(NftBuner);
const bunerInstance = await NftBuner.deployed();
if (bunerInstance) {
console.log("NftBuner successfully deployed.");
console.log("address: " + bunerInstance.address);
}
base.updateArray({
name: "NftBuner",
type: "logic",
json: "assets/contracts/NftBuner.json",
address: bunerInstance.address,
network,
});
let cfgs = base.loadData({ network });
const gacha = cfgs.find((c) => c.name === "Gacha").address
const gachaInstance = await Badge.at(gacha);
await gachaInstance.setBurnRole(bunerInstance.address);
console.log("gacha setBurnRole successfully deployed.");
const candy = cfgs.find((c) => c.name === "Candy").address
const candyInstance = await Badge.at(candy);
await candyInstance.setBurnRole(bunerInstance.address);
console.log("candy setBurnRole successfully deployed.");
const explorer = cfgs.find((c) => c.name === "Explorer").address
const explorerInstance = await NFTSbt.at(explorer);
await explorerInstance.setBurnRole(bunerInstance.address);
console.log("explorer setBurnRole successfully deployed.");
};

View File

@ -1,4 +1,5 @@
const Badge = artifacts.require("tokens/erc721/BEBadge"); const Badge = artifacts.require("tokens/erc721/BEBadge");
const NFTSbt = artifacts.require("tokens/erc721/NFTSbt");
const Coin = artifacts.require("tokens/erc20/BEUSDT"); const Coin = artifacts.require("tokens/erc20/BEUSDT");
const Wallet = artifacts.require("core/BEMultiSigWallet"); const Wallet = artifacts.require("core/BEMultiSigWallet");
const Distributor = artifacts.require("logic/NftDistributor"); const Distributor = artifacts.require("logic/NftDistributor");
@ -6,79 +7,106 @@ const base = require("../scripts/base");
module.exports = async function (deployer, network, accounts) { module.exports = async function (deployer, network, accounts) {
const config = require(`../config/config_${network}`); const config = require(`../config/config_${network}`);
await deployer.deploy(Badge, "BE Badge", "Badge", "4000");
await deployer.deploy(NFTSbt, "BE Explorer", "Explorer", "0");
const badgeInstance = await Badge.deployed(); const badgeInstance = await Badge.deployed();
if (badgeInstance) { if (badgeInstance) {
console.log("BEBadge successfully deployed. "); console.log("BEBadge successfully deployed. ");
console.log("address: " + badgeInstance.address); console.log("address: " + badgeInstance.address);
} }
base.updateArray({ base.updateArray({
name: "BEBadge", name: "Explorer",
type: "erc721", type: "erc721",
json: "assets/contracts/BEBadge.json", json: "assets/contracts/NFTSbt.json",
address: badgeInstance.address, address: badgeInstance.address,
network, network,
}); });
// await deployer.deploy(Badge, "BE Candy", "Candy", "0");
// const badgeInstance = await Badge.deployed();
// if (badgeInstance) {
// console.log("BEBadge successfully deployed. ");
// console.log("address: " + badgeInstance.address);
// }
// base.updateArray({
// name: "Candy",
// type: "erc721",
// json: "assets/contracts/BEBadge.json",
// address: badgeInstance.address,
// network,
// });
// await deployer.deploy(Badge, "BE Badge", "Badge", "4000");
// const badgeInstance = await Badge.deployed();
// if (badgeInstance) {
// console.log("BEBadge successfully deployed. ");
// console.log("address: " + badgeInstance.address);
// }
// base.updateArray({
// name: "BEBadge",
// type: "erc721",
// json: "assets/contracts/BEBadge.json",
// address: badgeInstance.address,
// network,
// });
await deployer.deploy(Coin, "BE test USDT", "USDT"); // await deployer.deploy(Coin, "BE test USDT", "USDT");
const coinInstance = await Coin.deployed(); // const coinInstance = await Coin.deployed();
if (coinInstance) { // if (coinInstance) {
console.log("BEUSDT successfully deployed. "); // console.log("BEUSDT successfully deployed. ");
console.log("address: " + coinInstance.address); // console.log("address: " + coinInstance.address);
} // }
base.updateArray({ // base.updateArray({
name: "BEUSDT", // name: "BEUSDT",
type: "erc20", // type: "erc20",
json: "assets/contracts/BEUSDT.json", // json: "assets/contracts/BEUSDT.json",
address: coinInstance.address, // address: coinInstance.address,
network, // network,
}); // });
await deployer.deploy( // await deployer.deploy(
Wallet, // Wallet,
60, // 60,
1, // 1,
config.admins.proposers, // config.admins.proposers,
config.admins.confirmers, // config.admins.confirmers,
config.admins.executors // config.admins.executors
); // );
const walletInstance = await Wallet.deployed(); // const walletInstance = await Wallet.deployed();
if (walletInstance) { // if (walletInstance) {
console.log("BEMultiSigWallet successfully deployed."); // console.log("BEMultiSigWallet successfully deployed.");
console.log("address: " + walletInstance.address); // console.log("address: " + walletInstance.address);
} // }
base.updateArray({ // base.updateArray({
name: "BEMultiSigWallet", // name: "BEMultiSigWallet",
type: "logic", // type: "logic",
json: "assets/contracts/BEMultiSigWallet.json", // json: "assets/contracts/BEMultiSigWallet.json",
address: walletInstance.address, // address: walletInstance.address,
network, // network,
}); // });
await badgeInstance.setMintRole(walletInstance.address); // await badgeInstance.setMintRole(walletInstance.address);
console.log("success add wallet to badge's mint role"); // console.log("success add wallet to badge's mint role");
await coinInstance.setMintRole(walletInstance.address); // await coinInstance.setMintRole(walletInstance.address);
console.log("success add wallet to usdt's mint role"); // console.log("success add wallet to usdt's mint role");
await deployer.deploy( // await deployer.deploy(
Distributor, // Distributor,
badgeInstance.address, // badgeInstance.address,
config.admins.executors // config.admins.executors
); // );
const distributorInstance = await Distributor.deployed(); // const distributorInstance = await Distributor.deployed();
if (distributorInstance) { // if (distributorInstance) {
console.log("NftDistributor successfully deployed."); // console.log("NftDistributor successfully deployed.");
console.log("address: " + distributorInstance.address); // console.log("address: " + distributorInstance.address);
} // }
base.updateArray({ // base.updateArray({
name: "NftDistributor", // name: "NftDistributor",
type: "logic", // type: "logic",
json: "assets/contracts/NftDistributor.json", // json: "assets/contracts/NftDistributor.json",
address: distributorInstance.address, // address: distributorInstance.address,
network, // network,
}); // });
await badgeInstance.setMintRole(distributorInstance.address); // await badgeInstance.setMintRole(distributorInstance.address);
await distributorInstance.grantRole( // await distributorInstance.grantRole(
"0xa076a07f65bcd51bcb15a0f01a65bc18f2d922acb81bcfd8af4caf5adb557091", // "0xa076a07f65bcd51bcb15a0f01a65bc18f2d922acb81bcfd8af4caf5adb557091",
walletInstance.address // walletInstance.address
); // );
console.log("success add distributor to badge's mint role"); // console.log("success add distributor to badge's mint role");
}; };

View File

@ -3,10 +3,10 @@ const base = require("../scripts/base");
module.exports = async function (deployer, network, accounts) { module.exports = async function (deployer, network, accounts) {
// const tokens = [{ name: "HERO", desc: "CRYPTO ELITE'S HERO", limit: 0 }]; // const tokens = [{ name: "HERO", desc: "CRYPTO ELITE'S HERO", limit: 0 }];
const tokens = [ const tokens = [
{ name: "HERO", desc: "CRYPTO ELITE'S HERO", limit: 0 }, // { name: "HERO", desc: "CRYPTO ELITE'S HERO", limit: 0 },
{ name: "PLANET", desc: "CF PLANET", limit: 0 }, // { name: "PLANET", desc: "CF PLANET", limit: 0 },
{ name: "TestHERO", desc: "CRYPTO ELITE'S HERO", limit: 0 }, { name: "TestHERO", desc: "CRYPTO ELITE'S HERO", limit: 0 },
{ name: "GoldBrick", desc: "CRYPTO ELITE'S GOLDBRICK", limit: 0 }, // { name: "GoldBrick", desc: "CRYPTO ELITE'S GOLDBRICK", limit: 0 },
]; ];
for (let i = 0, l = tokens.length; i < l; i++) { for (let i = 0, l = tokens.length; i < l; i++) {
const { name, desc, limit } = tokens[i]; const { name, desc, limit } = tokens[i];

View File

@ -53,12 +53,6 @@
"json": "assets/contracts/NFT.json", "json": "assets/contracts/NFT.json",
"address": "0x8ee0a9D6025A46f21c9b0b75a8472D001d94e8A7" "address": "0x8ee0a9D6025A46f21c9b0b75a8472D001d94e8A7"
}, },
{
"name": "TestHERO",
"type": "erc721",
"json": "assets/contracts/NFT.json",
"address": "0xCD4bb3402f1a444a1AF10F31946Ed37DaC0eaC4d"
},
{ {
"name": "GoldBrick", "name": "GoldBrick",
"type": "erc721", "type": "erc721",
@ -136,5 +130,29 @@
"type": "logic", "type": "logic",
"json": "assets/contracts/GoldBricksFactory.json", "json": "assets/contracts/GoldBricksFactory.json",
"address": "0x45E2Eae3634a69Fb9242397A75dd5751aEa8041e" "address": "0x45E2Eae3634a69Fb9242397A75dd5751aEa8041e"
},
{
"name": "Candy",
"type": "erc721",
"json": "assets/contracts/BEBadge.json",
"address": "0x6a673D946a976776fd5F163d9d831b2fEB600015"
},
{
"name": "Explorer",
"type": "erc721",
"json": "assets/contracts/NFTSbt.json",
"address": "0x7b6399DFbed8Bc46F6A498C6B1040E80c2B5C4bc"
},
{
"name": "TestHERO",
"type": "erc721",
"json": "assets/contracts/NFT.json",
"address": "0xCD4bb3402f1a444a1AF10F31946Ed37DaC0eaC4d"
},
{
"name": "NftBuner",
"type": "logic",
"json": "assets/contracts/NftBuner.json",
"address": "0xca5525178b0826A7C0835F0b7a383C802e10b6c7"
} }
] ]

54
test/burn.test.js Normal file
View File

@ -0,0 +1,54 @@
const NftBuner = artifacts.require("NftBuner");
const BEBadge = artifacts.require("BEBadge");
const NFTSbt = artifacts.require("NFTSbt");
const {
BN,
constants,
expectEvent,
expectRevert,
} = require("@openzeppelin/test-helpers");
const Web3 = require("web3");
contract("NftBuner", (accounts) => {
let nftBuner;
let badge;
let sbt;
const owner = accounts[0];
const user = accounts[1];
const executor = accounts[2];
let web3 = new Web3(Web3.givenProvider);
beforeEach(async () => {
badge = await BEBadge.new("CRYPTO ELITE'S HERO", "HERO", 0);
sbt = await NFTSbt.new("CRYPTO ELITE'S HERO", "SBT", 0);
nftBuner = await NftBuner.new();
await badge.setBurnRole(nftBuner.address);
await sbt.setBurnRole(nftBuner.address);
});
it("should burn the badge", async () => {
await badge.batchMint(user, 2, { from: owner });
const receipt = await nftBuner.brunBadge(
badge.address,
[1, 2],
{ from: user }
);
const balanceOfUser = await badge.balanceOf(user);
assert.equal(balanceOfUser, 0, "Incorrect user balance");
});
it("should burn the sbt", async () => {
await sbt.batchMint(user, 2, { from: owner });
await sbt.setApprovalForAll(nftBuner.address, true, { from: user });
const receipt = await nftBuner.burnSbt(
sbt.address,
[1, 2],
{ from: user }
);
console.log(receipt);
const balanceOfUser = await sbt.balanceOf(user);
assert.equal(balanceOfUser, 0, "Incorrect user balance");
});
});