Skip to content

Commit

Permalink
fix: more optimized burn
Browse files Browse the repository at this point in the history
  • Loading branch information
aaitor committed Nov 26, 2024
1 parent 636966f commit 660d0b9
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 52 deletions.
13 changes: 13 additions & 0 deletions contracts/token/NFTBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,17 @@ abstract contract NFTBase is IERC2981Upgradeable, CommonOwnable, AccessControlUp
function nftType() external pure virtual returns (bytes32) {
return keccak256('');
}

error BatchError(bytes innerError);

function _getRevertMsg(bytes memory _returnData) internal pure{
// If the _res length is less than 68, then
// the transaction failed with custom error or silently (without a revert message)
if (_returnData.length < 68) revert BatchError(_returnData);

// Slice the sighash.
// solhint-disable-next-line
assembly { _returnData := add(_returnData, 0x04) }
revert(abi.decode(_returnData, (string))); // All that remains is the revert string
}
}
25 changes: 19 additions & 6 deletions contracts/token/erc1155/NFT1155SubscriptionUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,25 @@ contract NFT1155SubscriptionUpgradeable is NFT1155Upgradeable {
function burnBatchFromHolders(
address[] memory from,
uint256[] memory ids,
uint256[] memory amounts
) external {
require(ids.length == amounts.length, 'burnBatch: lengths do not match');
require(ids.length == from.length, 'burnBatch: lengths do not match');
for (uint i = 0; i < ids.length; i++) {
burn(from[i], ids[i], amounts[i]);
uint256[] memory amounts,
bool revertOnFail
) external returns (bool[] memory successes, bytes[] memory results) {
uint256 _length = ids.length;
require(_length == amounts.length && _length == from.length, 'lengths do not match');

successes = new bool[](_length);
results = new bytes[](_length);

for (uint256 i = 0; i < _length; ++i) {
// solhint-disable-next-line
(bool success, bytes memory result) = address(this).delegatecall(abi.encodeWithSignature('burn(address,uint256,uint256)', from[i], ids[i], amounts[i]));

if (!success && revertOnFail) {
_getRevertMsg(result);
}
successes[i] = success;
results[i] = result;
}
return (successes, results);
}
}
66 changes: 23 additions & 43 deletions contracts/token/erc1155/NFT1155SubscriptionWithoutBlocks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,49 +75,15 @@ contract NFT1155SubscriptionWithoutBlocks is NFT1155Upgradeable {
*/
function balanceOf(address account, uint256 tokenId) public view virtual override returns (uint256) {
return super.balanceOf(account, tokenId);
// bytes32 _key = _getTokenKey(account, tokenId);
// uint256 _amountBurned;
// uint256 _amountMinted;
// for (uint index = 0; index < _tokens[_key].length; index++) {
// if (_tokens[_key][index].mintBlock > 0 &&
// (_tokens[_key][index].expirationBlock == 0 || _tokens[_key][index].expirationBlock > block.number)) {
// if (_tokens[_key][index].isMintOps)
// _amountMinted += _tokens[_key][index].amountMinted;
// else
// _amountBurned += _tokens[_key][index].amountMinted;
// }
// }
//
// if (_amountBurned >= _amountMinted)
// return 0;
// else
// return _amountMinted - _amountBurned;
}

// function whenWasMinted(address owner, uint256 tokenId) public view returns (uint256[] memory) {
// bytes32 _key = _getTokenKey(owner, tokenId);
// uint256[] memory _whenMinted = new uint256[](_tokens[_key].length);
// for (uint index = 0; index < _tokens[_key].length; index++) {
// _whenMinted[index] = _tokens[_key][index].mintBlock;
// }
// return _whenMinted;
// }
//
// function getMintedEntries(address owner, uint256 tokenId) public view returns (MintedTokens[] memory) {
// return _tokens[_getTokenKey(owner, tokenId)];
// }
//
// function _getTokenKey(address account, uint256 tokenId) internal pure returns (bytes32) {
// return keccak256(abi.encode(account, tokenId));
// }
}

function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external {
require(ids.length == amounts.length, 'mintBatch: lengths do not match');
require(ids.length == amounts.length, 'lengths do not match');
for (uint i = 0; i < ids.length; i++) {
mint(to, ids[i], amounts[i], data);
}
Expand All @@ -128,7 +94,7 @@ contract NFT1155SubscriptionWithoutBlocks is NFT1155Upgradeable {
uint256[] memory ids,
uint256[] memory amounts
) external {
require(ids.length == amounts.length, 'burnBatch: lengths do not match');
require(ids.length == amounts.length, 'lengths do not match');
for (uint i = 0; i < ids.length; i++) {
burn(from, ids[i], amounts[i]);
}
Expand All @@ -137,12 +103,26 @@ contract NFT1155SubscriptionWithoutBlocks is NFT1155Upgradeable {
function burnBatchFromHolders(
address[] memory from,
uint256[] memory ids,
uint256[] memory amounts
) external {
require(ids.length == amounts.length, 'burnBatch: lengths do not match');
require(ids.length == from.length, 'burnBatch: lengths do not match');
for (uint i = 0; i < ids.length; i++) {
burn(from[i], ids[i], amounts[i]);
uint256[] memory amounts,
bool revertOnFail
) external returns (bool[] memory successes, bytes[] memory results) {
uint256 _length = ids.length;
require(_length == amounts.length && _length == from.length, 'lengths do not match');

successes = new bool[](_length);
results = new bytes[](_length);

for (uint256 i = 0; i < _length; ++i) {
// solhint-disable-next-line
(bool success, bytes memory result) = address(this).delegatecall(abi.encodeWithSignature('burn(address,uint256,uint256)', from[i], ids[i], amounts[i]));

if (!success && revertOnFail) {
_getRevertMsg(result);
}
successes[i] = success;
results[i] = result;
}
return (successes, results);
}

}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nevermined-io/contracts",
"version": "3.5.9",
"version": "3.5.10",
"description": "Nevermined implementation of Nevermined in Solidity",
"bugs": {
"url": "https://github.com/nevermined-io/contracts/issues"
Expand Down
7 changes: 5 additions & 2 deletions test/unit/token/NFT1155SubscriptionWithoutBlocks.Test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ contract('NFT1155 Subscription', (accounts) => {
deployer,
minter,
account1,
account2
account2,
account3
] = accounts

let nft
Expand Down Expand Up @@ -154,7 +155,9 @@ contract('NFT1155 Subscription', (accounts) => {
assert.strictEqual(balances[0], 23)
assert.strictEqual(balances[1], 15)

await nft.burnBatchFromHolders([account2, account2], [tokenId3, tokenId4], [22, 14], { from: minter })
await nft.mintBatch(account3, [tokenId3, tokenId4], [50, 50], data, { from: minter })

await nft.burnBatchFromHolders([account2, account3, account2], [tokenId3, tokenId3, tokenId4], [22, 10, 14], { from: minter })
balance = new BigNumber(await nft.balanceOf(account2, tokenId3))
balance2 = new BigNumber(await nft.balanceOf(account2, tokenId4))
assert.strictEqual(balance.toNumber(), 1)
Expand Down

0 comments on commit 660d0b9

Please sign in to comment.