Skip to content

Commit

Permalink
allow burn token with proper flag
Browse files Browse the repository at this point in the history
  • Loading branch information
jollyjoker992 committed Jan 12, 2024
1 parent 213d6a7 commit e630832
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 18 deletions.
51 changes: 37 additions & 14 deletions contracts/FeralFileAirdropV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,27 @@ contract FeralFileAirdropV1 is ERC1155, Authorizable {
// Airdropped addresses
mapping(address => bool) public airdroppedAddresses;

// already ended flag
bool private _ended;

// Token type
Type public tokenType;

constructor(Type tokenType_, string memory tokenURI_) ERC1155(tokenURI_) {
// Burnable flag
bool public burnable;

// Bridgeable flag
bool public bridgeable;

// Ended flag
bool private _ended;

constructor(
Type tokenType_,
string memory tokenURI_,
bool burnable_,
bool bridgeable_
) ERC1155(tokenURI_) {
tokenType = tokenType_;
burnable = burnable_;
bridgeable = bridgeable_;
}

// @notice check if the airdrop is ended
Expand All @@ -42,11 +55,7 @@ contract FeralFileAirdropV1 is ERC1155, Authorizable {
/// @param amount_ amount of tokens to mint
function mint(uint256 tokenID_, uint256 amount_) external onlyAuthorized {
require(!_ended, "FeralFileAirdropV1: already ended");
require(
(tokenType == Type.Fungible && amount_ > 0) ||
(tokenType == Type.NonFungible && amount_ == 1),
"FeralFileAirdropV1: amount mismatch"
);
_checkProperTokenAmount(amount_);
_mint(address(this), tokenID_, amount_, "");
}

Expand All @@ -58,11 +67,7 @@ contract FeralFileAirdropV1 is ERC1155, Authorizable {
address[] calldata to_
) external onlyAuthorized {
require(!_ended, "FeralFileAirdropV1: already ended");
require(
(tokenType == Type.Fungible && to_.length > 0) ||
(tokenType == Type.NonFungible && to_.length == 1),
"FeralFileAirdropV1: amount mismatch"
);
_checkProperTokenAmount(to_.length); // to_ length is the amount of tokens to airdrop

uint256[] memory _tokenIDs = new uint256[](1);
_tokenIDs[0] = tokenID_;
Expand Down Expand Up @@ -94,6 +99,24 @@ contract FeralFileAirdropV1 is ERC1155, Authorizable {
_burn(address(this), tokenID_, balanceOf(address(this), tokenID_));
}

/// @notice burn tokens
/// @param tokenID_ token ID
/// @param amount_ amount of tokens to burn
function burn(uint256 tokenID_, uint256 amount_) external {
require(burnable, "FeralFileAirdropV1: not burnable");
_checkProperTokenAmount(amount_);
_burn(_msgSender(), tokenID_, amount_);
}

/// @notice check proper amount of tokens
function _checkProperTokenAmount(uint256 amount_) internal view {
require(
(tokenType == Type.Fungible && amount_ > 0) ||
(tokenType == Type.NonFungible && amount_ == 1),
"FeralFileAirdropV1: amount mismatch"
);
}

function onERC1155Received(
address,
address from_,
Expand Down
4 changes: 3 additions & 1 deletion migrations/310_feralfile_airdrop_v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module.exports = function (deployer) {
argv.token_uri ||
"https://ipfs.bitmark.com/ipfs/QmNVdQSp1AvZonLwHzTbbZDPLgbpty15RMQrbPEWd4ooTU/{id}";
let type = argv.type || 0;
let burnable = argv.burnable || true;
let bridgeable = argv.bridgeable || true;

deployer.deploy(FeralFileAirdropV1, type, token_uri);
deployer.deploy(FeralFileAirdropV1, type, token_uri, burnable, bridgeable);
};
89 changes: 86 additions & 3 deletions test/feralfile_airdrop_v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,23 @@ contract("FeralFileAirdropV1", async (accounts) => {
// To isolate the test cases, we create multiple pairs of contracts
// for each token type. The index of the contract pair will be used
// as index of test cases.
for (let i = 0; i < 5; i++) {
for (let i = 0; i < 7; i++) {
let burnable = i == 6 ? false : true;
let bridgeable = true;
let fungibleContract = await FeralFileAirdropV1.new(
TOKEN_TYPE_FUNGIBLE,
TOKEN_URI
TOKEN_URI,
burnable,
bridgeable
);
await fungibleContract.addTrustee(this.trustee, {
from: this.owner,
});
let nonFungibleContract = await FeralFileAirdropV1.new(
TOKEN_TYPE_NON_FUNGIBLE,
TOKEN_URI
TOKEN_URI,
burnable,
bridgeable
);
await nonFungibleContract.addTrustee(this.trustee, {
from: this.owner,
Expand Down Expand Up @@ -269,4 +275,81 @@ contract("FeralFileAirdropV1", async (accounts) => {
assert.equal(afterBalance.toNumber(), 0);
}
});

it("test burn with burnable=true", async () => {
let contracts = this.contracts[5]; // burnable=true
for (let i = 0; i < contracts.length; i++) {
let contract = contracts[i];

// mint token to prepare for below tests
let correctAmount = i == 0 ? 10 : 1;
await contract.mint(TOKEN_ID, correctAmount, {
from: this.trustee,
});

recipient = accounts[0];
// test insufficient balance
try {
await contract.burn(TOKEN_ID, correctAmount, {
from: recipient,
});
} catch (e) {
assert.equal(e.reason, "ERC1155: burn amount exceeds balance");
}

// airdrop to recipient
await contract.airdrop(TOKEN_ID, [recipient], {
from: this.trustee,
});

// test burn amount mismatch
wrongAmount = i == 0 ? 0 : 2;
try {
await contract.burn(TOKEN_ID, wrongAmount, { from: recipient });
} catch (e) {
assert.equal(e.reason, "FeralFileAirdropV1: amount mismatch");
}

// test burn successfully
let beforeBalance = await contract.balanceOf(recipient, TOKEN_ID);
assert.equal(beforeBalance.toNumber(), 1);

await contract.burn(TOKEN_ID, 1, { from: this.owner });

let afterBalance = await contract.balanceOf(recipient, TOKEN_ID);
assert.equal(afterBalance.toNumber(), 0);
}
});

it("test burn with burnable=false", async () => {
let contracts = this.contracts[6]; // burnable=false
for (let i = 0; i < contracts.length; i++) {
let contract = contracts[i];

// make sure burnable=false
assert.equal(await contract.burnable(), false);

// mint token to prepare for below tests
let correctAmount = i == 0 ? 10 : 1;
await contract.mint(TOKEN_ID, correctAmount, {
from: this.trustee,
});

burner = accounts[0];
// airdrop to burner
await contract.airdrop(TOKEN_ID, [burner], {
from: this.trustee,
});

// make sure burner has sufficient balance
assert.equal(await contract.balanceOf(burner, TOKEN_ID), 1);

// test burn fails due to the burnable=false
try {
await contract.burn(TOKEN_ID, 1, { from: burner });
} catch (e) {
assert.equal(e.reason, "FeralFileAirdropV1: not burnable");
}
}
});
});

0 comments on commit e630832

Please sign in to comment.