Files
simplex-chat/eth/nft/tests/MultiERC1155_test.sol
Evgeny 6138c8e66b tokens: ERC1155 contract for tokens (#6376)
* tokens: ERC1155 contract for tokens

* simplify 1155

* NFT and minter contracts

* update NFT

* update

* update

* update

* update

* NFT metadata JSON

* update token metadata

* flattened contracts
2025-10-28 22:12:47 +00:00

337 lines
14 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import "remix_tests.sol";
import "../contracts/MultiERC1155.sol";
contract MultiERC1155Test {
MultiERC1155 public ct;
address public owner = address(this);
address public admin = address(0x1);
address public minter = address(0x2);
address public user = address(0x3);
address public recipient = address(0x4);
MultiERC1155.TokenInfo defaultInfo = MultiERC1155.TokenInfo({
tokenUri: "https://example.com/token.json",
totalSupply: 0,
enabled: true
});
function beforeAll() public {
ct = new MultiERC1155();
MultiERC1155.TokenInfo memory newInfo = defaultInfo;
(bool success, ) = address(ct).call(abi.encodeWithSignature("addToken((string,bool,string,string,string,uint256))", newInfo));
Assert.equal(success, true, "addToken success");
}
// Constructor Test
function testConstructor() public {
Assert.equal(ct.owner(), owner, "Owner should be deployer");
Assert.equal(ct.admin(), owner, "Admin should be deployer");
Assert.equal(ct.minter(), owner, "Minter should be deployer");
Assert.equal(ct.mintingEnabled(), true, "Minting should be enabled");
Assert.equal(ct.contractLocked(), false, "Contract should not be locked");
uint[] memory ids = ct.getTokenIds();
Assert.equal(ids.length, uint(1), "One token ID added");
Assert.equal(ids[0], uint(1), "First token ID is 1");
(, uint currentSupply, bool exists, bool locked) = ct.tokens(1);
Assert.equal(exists, true, "Token 1 exists");
Assert.equal(locked, false, "Token 1 not locked");
Assert.equal(currentSupply, uint(0), "Token 1 supply 0");
}
// setAdmin Test
function testSetAdmin() public {
ct.setAdmin(admin);
Assert.equal(ct.admin(), admin, "Admin updated");
}
function testSetAdminOnlyOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("setAdmin(address)", admin));
Assert.equal(success, true, "Set admin from owner succeeds"); // Since this is owner
// To test revert, Remix plugin runs as this, so for non-owner, manual simulation not easy; note as TODO or skip
}
// setMinter Test
function testSetMinter() public {
ct.setMinter(minter);
Assert.equal(ct.minter(), minter, "Minter updated");
}
function testSetMinterOnlyOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("setMinter(address)", minter));
Assert.equal(success, true, "Set minter from owner succeeds");
}
// toggleMinting Test
function testToggleMinting() public {
ct.toggleMinting(false);
Assert.equal(ct.mintingEnabled(), false, "Minting disabled");
ct.toggleMinting(true);
Assert.equal(ct.mintingEnabled(), true, "Minting enabled");
}
function testToggleMintingNoChange() public {
ct.toggleMinting(true); // Already true
Assert.equal(ct.mintingEnabled(), true, "No change if same");
}
function testToggleMintingOnlyOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("toggleMinting(bool)", false));
Assert.equal(success, true, "Toggle from owner succeeds");
}
// lockContract Test
function testLockContract() public {
ct.lockContract();
Assert.equal(ct.contractLocked(), true, "Contract locked");
Assert.equal(ct.mintingEnabled(), false, "Minting disabled");
}
function testLockContractOnlyOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("lockContract()"));
Assert.equal(success, true, "Lock from owner succeeds");
}
// addToken Test
function testAddToken() public {
MultiERC1155.TokenInfo memory newInfo = MultiERC1155.TokenInfo({
tokenUri: "https://example.com/new_token.json",
totalSupply: 100,
enabled: true
});
ct.addToken(newInfo);
uint[] memory ids = ct.getTokenIds();
Assert.equal(ids.length, uint(2), "Two token IDs");
Assert.equal(ids[1], uint(2), "Second token ID 2");
(MultiERC1155.TokenInfo memory tokenInfo, uint currentSupply, bool exists, bool locked) = ct.tokens(2);
Assert.equal(exists, true, "Token 2 exists");
Assert.equal(locked, false, "Token 2 not locked");
Assert.equal(currentSupply, uint(0), "Token 2 supply 0");
Assert.equal(tokenInfo.totalSupply, uint(100), "Token 2 totalSupply 100");
// Validate info fields as needed
}
function testAddTokenByAdmin() public {
ct.setAdmin(admin);
MultiERC1155.TokenInfo memory newInfo = defaultInfo;
(bool success, ) = address(ct).call(abi.encodeWithSignature("addToken((string,bool,string,string,string,uint256))", newInfo));
Assert.equal(success, true, "Add by admin succeeds");
uint[] memory ids = ct.getTokenIds();
Assert.equal(ids.length, uint(2), "Two token IDs");
}
function testAddTokenRevertInvalidInfo() public {
MultiERC1155.TokenInfo memory invalidInfo = MultiERC1155.TokenInfo({
tokenUri: "",
totalSupply: 0,
enabled: true
});
(bool success, ) = address(ct).call(abi.encodeWithSignature("addToken((string,bool,string,string,string,uint256))", invalidInfo));
Assert.equal(success, false, "Invalid info reverts");
}
function testAddTokenOnlyAdminOrOwner() public {
MultiERC1155.TokenInfo memory info = defaultInfo;
(bool success, ) = address(ct).call(abi.encodeWithSignature("addToken((string,bool,string,string,string,uint256))", info));
Assert.equal(success, true, "Add from owner succeeds");
}
// removeToken Test
function testRemoveToken() public {
MultiERC1155.TokenInfo memory newInfo = defaultInfo;
ct.addToken(newInfo);
uint[] memory ids = ct.getTokenIds();
Assert.equal(ids.length, uint(2), "Two token IDs");
ct.removeToken(2);
ids = ct.getTokenIds();
Assert.equal(ids.length, uint(1), "One token ID after removal");
(,,bool exists,) = ct.tokens(2);
Assert.equal(exists, false, "Token 2 removed");
}
function testRemoveTokenRevertNonExist() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("removeToken(uint256)", 99));
Assert.equal(success, false, "Remove non-exist reverts");
}
function testRemoveTokenRevertHasSupply() public {
ct.mint(user, 1, 10, "");
(bool success,) = address(ct).call(abi.encodeWithSignature("removeToken(uint256)", 1));
Assert.equal(success, false, "Remove with supply reverts");
}
function testRemoveTokenRevertLast() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("removeToken(uint256)", 1));
Assert.equal(success, false, "Remove last reverts");
}
function testRemoveTokenOnlyAdminOrOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("removeToken(uint256)", 1));
Assert.equal(success, false, "Remove last fails"); // But for non-owner, need simulation
}
// updateToken Test
function testUpdateToken() public {
ct.updateToken(1, false, 100);
(MultiERC1155.TokenInfo memory tokenInfo,,,) = ct.tokens(1);
Assert.equal(tokenInfo.enabled, false, "Enabled updated");
Assert.equal(tokenInfo.totalSupply, uint(100), "Total supply updated");
}
function testUpdateTokenNoChange() public {
(MultiERC1155.TokenInfo memory tokenInfo,,,) = ct.tokens(1);
ct.updateToken(1, tokenInfo.enabled, tokenInfo.totalSupply);
// No assert, as no change
}
function testUpdateTokenRevertNonExist() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("updateToken(uint256,bool,uint256)", 99, true, 0));
Assert.equal(success, false, "Update non-exist reverts");
}
function testUpdateTokenRevertLocked() public {
ct.mint(user, 1, 10, "");
ct.lockToken(1);
(bool success, ) = address(ct).call(abi.encodeWithSignature("updateToken(uint256,bool,uint256)", 1, true, 0));
Assert.equal(success, false, "Update locked reverts");
}
function testUpdateTokenRevertInvalidSupply() public {
ct.mint(user, 1, 10, "");
(bool success, ) = address(ct).call(abi.encodeWithSignature("updateToken(uint256,bool,uint256)", 1, true, 5));
Assert.equal(success, false, "Invalid supply reverts");
}
function testUpdateTokenOnlyAdminOrOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("updateToken(uint256,bool,uint256)", 1, true, 0));
Assert.equal(success, true, "Update from owner succeeds");
}
// lockToken Test
function testLockToken() public {
ct.mint(user, 1, 10, "");
ct.lockToken(1);
(MultiERC1155.TokenInfo memory tokenInfo,,, bool locked) = ct.tokens(1);
Assert.equal(locked, true, "Token locked");
Assert.equal(tokenInfo.enabled, false, "Enabled false");
}
function testLockTokenRevertNonExist() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("lockToken(uint256)", 99));
Assert.equal(success, false, "Lock non-exist reverts");
}
function testLockTokenRevertAlreadyLocked() public {
ct.mint(user, 1, 10, "");
ct.lockToken(1);
(bool success, ) = address(ct).call(abi.encodeWithSignature("lockToken(uint256)", 1));
Assert.equal(success, false, "Lock already locked reverts");
}
function testLockTokenRevertNoSupply() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("lockToken(uint256)", 1));
Assert.equal(success, false, "Lock no supply reverts");
}
function testLockTokenOnlyOwner() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("lockToken(uint256)", 1));
Assert.equal(success, false, "Lock no supply fails"); // Test with supply
}
// mint Test
function testMint() public {
ct.mint(user, 1, 10, "");
Assert.equal(ct.balanceOf(user, 1), 10, "User balance 10");
(,uint currentSupply,,) = ct.tokens(1);
Assert.equal(currentSupply, 10, "Token supply 10");
}
function testMintRevertLockedContract() public {
ct.lockContract();
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 10, ""));
Assert.equal(success, false, "Mint locked contract reverts");
}
function testMintRevertMintingDisabled() public {
ct.toggleMinting(false);
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 10, ""));
Assert.equal(success, false, "Mint disabled reverts");
}
function testMintRevertInvalidCaller() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 10, ""));
Assert.equal(success, true, "Mint from owner succeeds");
}
function testMintRevertNonExist() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 99, 10, ""));
Assert.equal(success, false, "Mint non-exist reverts");
}
function testMintRevertLockedToken() public {
ct.mint(user, 1, 10, "");
ct.lockToken(1);
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 5, ""));
Assert.equal(success, false, "Mint locked token reverts");
}
function testMintRevertDisabledToken() public {
ct.updateToken(1, false, 0);
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 10, ""));
Assert.equal(success, false, "Mint disabled token reverts");
}
function testMintRevertSupplyExceeded() public {
ct.updateToken(1, true, 5);
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 10, ""));
Assert.equal(success, false, "Mint supply exceeded reverts");
}
function testMintRevertZeroAmount() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("mint(address,uint256,uint256,bytes)", user, 1, 0, ""));
Assert.equal(success, false, "Mint zero amount reverts");
}
// _update Test (via transfer/burn)
function testUpdateMint() public {
ct.mint(user, 1, 10, "");
(,uint currentSupply,,) = ct.tokens(1);
Assert.equal(currentSupply, 10, "Supply after mint");
}
function testUpdateBurn() public {
ct.mint(user, 1, 10, "");
(bool success, ) = address(ct).call(abi.encodeWithSignature("safeTransferFrom(address,address,uint256,uint256,bytes)", user, address(0), 1, 5, ""));
Assert.equal(success, true, "Burn succeeds");
(,uint currentSupply,,) = ct.tokens(1);
Assert.equal(currentSupply, 5, "Supply after burn");
}
function testUpdateTransfer() public {
ct.mint(user, 1, 10, "");
(bool success, ) = address(ct).call(abi.encodeWithSignature("safeTransferFrom(address,address,uint256,uint256,bytes)", user, recipient, 1, 5, ""));
Assert.equal(success, true, "Transfer succeeds");
(,uint currentSupply,,) = ct.tokens(1);
Assert.equal(currentSupply, 10, "Supply unchanged on transfer");
}
// uri Test
function testUri() public {
string memory json = Base64.encode(bytes('{"name":"Test Token","description":"Test Description","image":"https://test.com/image.png","properties":{}}'));
string memory expected = string.concat("data:application/json;base64,", json);
Assert.equal(ct.uri(1), expected, "URI matches");
}
function testUriRevertNonExist() public {
(bool success, ) = address(ct).call(abi.encodeWithSignature("uri(uint256)", 99));
Assert.equal(success, false, "URI non-exist reverts");
}
}