From cd2f5a22fc319c045500517a386f318a0416642f Mon Sep 17 00:00:00 2001 From: Roshan <19766713+rpalakkal@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:36:57 -0400 Subject: [PATCH] feat: batch redeemer --- .../42161/run-1727623676.json | 50 ++++++++++++++++++ .../42161/run-1727625207.json | 50 ++++++++++++++++++ .../42161/run-latest.json | 50 ++++++++++++++++++ script/NFT.s.sol | 7 +-- script/NFTBatchRedeem.s.sol | 15 ++++++ src/NFT.sol | 52 ++++--------------- src/NFTBatchRedeem.sol | 21 ++++++++ 7 files changed, 198 insertions(+), 47 deletions(-) create mode 100644 broadcast/NFTBatchRedeem.s.sol/42161/run-1727623676.json create mode 100644 broadcast/NFTBatchRedeem.s.sol/42161/run-1727625207.json create mode 100644 broadcast/NFTBatchRedeem.s.sol/42161/run-latest.json create mode 100644 script/NFTBatchRedeem.s.sol create mode 100644 src/NFTBatchRedeem.sol diff --git a/broadcast/NFTBatchRedeem.s.sol/42161/run-1727623676.json b/broadcast/NFTBatchRedeem.s.sol/42161/run-1727623676.json new file mode 100644 index 0000000..6da4efe --- /dev/null +++ b/broadcast/NFTBatchRedeem.s.sol/42161/run-1727623676.json @@ -0,0 +1,50 @@ +{ + "transactions": [ + { + "hash": "0x001689fb9041b37123a88cc6e2be22d0f8e3332b6b1b1729d0029a945ab9d97c", + "transactionType": "CREATE", + "contractName": "NFTBatchRedeem", + "contractAddress": "0x8d060dbbedb117e6f67e435a032dea69c4c4aebe", + "function": null, + "arguments": [ + "0xC8bBb02015a096F099DedA4eAD138c1Db069cd98" + ], + "transaction": { + "from": "0xa4d75b152d56d703d46b5a2c37096b3ecb06c7fd", + "gas": "0xd6a13", + "value": "0x0", + "input": "0x6080604052348015600f57600080fd5b50604051610353380380610353833981016040819052602c916050565b600080546001600160a01b0319166001600160a01b0392909216919091179055607e565b600060208284031215606157600080fd5b81516001600160a01b0381168114607757600080fd5b9392505050565b6102c68061008d6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063dc89605914610030575b600080fd5b61004361003e3660046100f5565b610045565b005b60005b828110156100d9576000546001600160a01b0316630d4c5fb2858584818110610073576100736101fe565b905060200201358460006040518463ffffffff1660e01b815260040161009b93929190610214565b600060405180830381600087803b1580156100b557600080fd5b505af11580156100c9573d6000803e3d6000fd5b5050600190920191506100489050565b50505050565b634e487b7160e01b600052604160045260246000fd5b60008060006040848603121561010a57600080fd5b833567ffffffffffffffff8082111561012257600080fd5b818601915086601f83011261013657600080fd5b81358181111561014557600080fd5b602088818360051b860101111561015b57600080fd5b80840196508195508088013593508284111561017657600080fd5b838801935088601f85011261018a57600080fd5b833591508282111561019e5761019e6100df565b604051601f8301601f19908116603f011681019084821181831017156101c6576101c66100df565b816040528381528a838588010111156101de57600080fd5b838387018483013760008385830101528096505050505050509250925092565b634e487b7160e01b600052603260045260246000fd5b8381526000602060606020840152845180606085015260005b818110156102495786810183015185820160800152820161022d565b506000608082860101526080601f19601f830116850101925050506002831061028257634e487b7160e01b600052602160045260246000fd5b82604083015294935050505056fea2646970667358221220fe0257ddcc60ab062b7614dd289e347ea8bb8200cd27eec47bd26d30cc26963e64736f6c63430008190033000000000000000000000000c8bbb02015a096f099deda4ead138c1db069cd98", + "nonce": "0xe2", + "chainId": "0xa4b1" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x1fac1a", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0x001689fb9041b37123a88cc6e2be22d0f8e3332b6b1b1729d0029a945ab9d97c", + "transactionIndex": "0x4", + "blockHash": "0x46c8489714912fc987f158660f85619da0800f6377ef48ea1d3f200928f2cf49", + "blockNumber": "0xf6a3b4c", + "gasUsed": "0x94444", + "effectiveGasPrice": "0x989680", + "from": "0xa4d75b152d56d703d46b5a2c37096b3ecb06c7fd", + "to": null, + "contractAddress": "0x8d060dbbedb117e6f67e435a032dea69c4c4aebe", + "gasUsedForL1": "0x5be6d", + "l1BlockNumber": "0x13e4164" + } + ], + "libraries": [], + "pending": [], + "returns": {}, + "timestamp": 1727623676, + "chain": 42161, + "commit": "0ace6b2" +} \ No newline at end of file diff --git a/broadcast/NFTBatchRedeem.s.sol/42161/run-1727625207.json b/broadcast/NFTBatchRedeem.s.sol/42161/run-1727625207.json new file mode 100644 index 0000000..61956d2 --- /dev/null +++ b/broadcast/NFTBatchRedeem.s.sol/42161/run-1727625207.json @@ -0,0 +1,50 @@ +{ + "transactions": [ + { + "hash": "0xdfc75793cee8c31f5357ef05ba5d52eaf571f05eebc97a52d6c23e70c1a32013", + "transactionType": "CREATE", + "contractName": "NFTBatchRedeem", + "contractAddress": "0x0b33bd59fca63390a341ee6f608bf5ed1393ffcc", + "function": null, + "arguments": [ + "0xC8bBb02015a096F099DedA4eAD138c1Db069cd98" + ], + "transaction": { + "from": "0xa4d75b152d56d703d46b5a2c37096b3ecb06c7fd", + "gas": "0xcad45", + "value": "0x0", + "input": "0x6080604052348015600f57600080fd5b50604051610449380380610449833981016040819052602c916050565b600080546001600160a01b0319166001600160a01b0392909216919091179055607e565b600060208284031215606157600080fd5b81516001600160a01b0381168114607757600080fd5b9392505050565b6103bc8061008d6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063150b7a021461003b578063dc89605914610076575b600080fd5b6100596100493660046101cd565b630a85bd0160e11b949350505050565b6040516001600160e01b0319909116815260200160405180910390f35b610089610084366004610249565b61008b565b005b60005b8281101561011f576000546001600160a01b0316630d4c5fb28585848181106100b9576100b96102f4565b905060200201358460006040518463ffffffff1660e01b81526004016100e19392919061030a565b600060405180830381600087803b1580156100fb57600080fd5b505af115801561010f573d6000803e3d6000fd5b50506001909201915061008e9050565b50505050565b80356001600160a01b038116811461013c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561017257610172610141565b604051601f8501601f19908116603f0116810190828211818310171561019a5761019a610141565b816040528093508581528686860111156101b357600080fd5b858560208301376000602087830101525050509392505050565b600080600080608085870312156101e357600080fd5b6101ec85610125565b93506101fa60208601610125565b925060408501359150606085013567ffffffffffffffff81111561021d57600080fd5b8501601f8101871361022e57600080fd5b61023d87823560208401610157565b91505092959194509250565b60008060006040848603121561025e57600080fd5b833567ffffffffffffffff8082111561027657600080fd5b818601915086601f83011261028a57600080fd5b81358181111561029957600080fd5b8760208260051b85010111156102ae57600080fd5b6020928301955093509085013590808211156102c957600080fd5b508401601f810186136102db57600080fd5b6102ea86823560208401610157565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b8381526000602060606020840152845180606085015260005b8181101561033f57868101830151858201608001528201610323565b506000608082860101526080601f19601f830116850101925050506002831061037857634e487b7160e01b600052602160045260246000fd5b82604083015294935050505056fea26469706673582212203218220d12e29ad6fd5c0f62034b95969090e50280834682ac7711f2dc42041164736f6c63430008190033000000000000000000000000c8bbb02015a096f099deda4ead138c1db069cd98", + "nonce": "0xfd", + "chainId": "0xa4b1" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0xfdae2", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0xdfc75793cee8c31f5357ef05ba5d52eaf571f05eebc97a52d6c23e70c1a32013", + "transactionIndex": "0x4", + "blockHash": "0x8677799132b00b44d05c3af2b2780582510410adf73fca7b0abf832b1b9d39db", + "blockNumber": "0xf6a5313", + "gasUsed": "0x8ec06", + "effectiveGasPrice": "0x989680", + "from": "0xa4d75b152d56d703d46b5a2c37096b3ecb06c7fd", + "to": null, + "contractAddress": "0x0b33bd59fca63390a341ee6f608bf5ed1393ffcc", + "gasUsedForL1": "0x49695", + "l1BlockNumber": "0x13e41e2" + } + ], + "libraries": [], + "pending": [], + "returns": {}, + "timestamp": 1727625207, + "chain": 42161, + "commit": "0ace6b2" +} \ No newline at end of file diff --git a/broadcast/NFTBatchRedeem.s.sol/42161/run-latest.json b/broadcast/NFTBatchRedeem.s.sol/42161/run-latest.json new file mode 100644 index 0000000..61956d2 --- /dev/null +++ b/broadcast/NFTBatchRedeem.s.sol/42161/run-latest.json @@ -0,0 +1,50 @@ +{ + "transactions": [ + { + "hash": "0xdfc75793cee8c31f5357ef05ba5d52eaf571f05eebc97a52d6c23e70c1a32013", + "transactionType": "CREATE", + "contractName": "NFTBatchRedeem", + "contractAddress": "0x0b33bd59fca63390a341ee6f608bf5ed1393ffcc", + "function": null, + "arguments": [ + "0xC8bBb02015a096F099DedA4eAD138c1Db069cd98" + ], + "transaction": { + "from": "0xa4d75b152d56d703d46b5a2c37096b3ecb06c7fd", + "gas": "0xcad45", + "value": "0x0", + "input": "0x6080604052348015600f57600080fd5b50604051610449380380610449833981016040819052602c916050565b600080546001600160a01b0319166001600160a01b0392909216919091179055607e565b600060208284031215606157600080fd5b81516001600160a01b0381168114607757600080fd5b9392505050565b6103bc8061008d6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063150b7a021461003b578063dc89605914610076575b600080fd5b6100596100493660046101cd565b630a85bd0160e11b949350505050565b6040516001600160e01b0319909116815260200160405180910390f35b610089610084366004610249565b61008b565b005b60005b8281101561011f576000546001600160a01b0316630d4c5fb28585848181106100b9576100b96102f4565b905060200201358460006040518463ffffffff1660e01b81526004016100e19392919061030a565b600060405180830381600087803b1580156100fb57600080fd5b505af115801561010f573d6000803e3d6000fd5b50506001909201915061008e9050565b50505050565b80356001600160a01b038116811461013c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561017257610172610141565b604051601f8501601f19908116603f0116810190828211818310171561019a5761019a610141565b816040528093508581528686860111156101b357600080fd5b858560208301376000602087830101525050509392505050565b600080600080608085870312156101e357600080fd5b6101ec85610125565b93506101fa60208601610125565b925060408501359150606085013567ffffffffffffffff81111561021d57600080fd5b8501601f8101871361022e57600080fd5b61023d87823560208401610157565b91505092959194509250565b60008060006040848603121561025e57600080fd5b833567ffffffffffffffff8082111561027657600080fd5b818601915086601f83011261028a57600080fd5b81358181111561029957600080fd5b8760208260051b85010111156102ae57600080fd5b6020928301955093509085013590808211156102c957600080fd5b508401601f810186136102db57600080fd5b6102ea86823560208401610157565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b8381526000602060606020840152845180606085015260005b8181101561033f57868101830151858201608001528201610323565b506000608082860101526080601f19601f830116850101925050506002831061037857634e487b7160e01b600052602160045260246000fd5b82604083015294935050505056fea26469706673582212203218220d12e29ad6fd5c0f62034b95969090e50280834682ac7711f2dc42041164736f6c63430008190033000000000000000000000000c8bbb02015a096f099deda4ead138c1db069cd98", + "nonce": "0xfd", + "chainId": "0xa4b1" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0xfdae2", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0xdfc75793cee8c31f5357ef05ba5d52eaf571f05eebc97a52d6c23e70c1a32013", + "transactionIndex": "0x4", + "blockHash": "0x8677799132b00b44d05c3af2b2780582510410adf73fca7b0abf832b1b9d39db", + "blockNumber": "0xf6a5313", + "gasUsed": "0x8ec06", + "effectiveGasPrice": "0x989680", + "from": "0xa4d75b152d56d703d46b5a2c37096b3ecb06c7fd", + "to": null, + "contractAddress": "0x0b33bd59fca63390a341ee6f608bf5ed1393ffcc", + "gasUsedForL1": "0x49695", + "l1BlockNumber": "0x13e41e2" + } + ], + "libraries": [], + "pending": [], + "returns": {}, + "timestamp": 1727625207, + "chain": 42161, + "commit": "0ace6b2" +} \ No newline at end of file diff --git a/script/NFT.s.sol b/script/NFT.s.sol index f78efe0..c6ff642 100644 --- a/script/NFT.s.sol +++ b/script/NFT.s.sol @@ -9,12 +9,7 @@ contract MyScript is Script { address minter = 0xA4D75b152D56D703D46B5a2c37096B3eCb06C7FD; vm.startBroadcast(deployerPrivateKey); - NFT nft = new NFT( - "Account.link", - "account.link", - "https://account.link/metadata/", - minter - ); + NFT nft = new NFT("Account.link", "account.link", "https://account.link/metadata/", minter); nft.whitelistMinter(minter); diff --git a/script/NFTBatchRedeem.s.sol b/script/NFTBatchRedeem.s.sol new file mode 100644 index 0000000..fb94b81 --- /dev/null +++ b/script/NFTBatchRedeem.s.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.8.20; + +import "forge-std/Script.sol"; +import "../src/NFTBatchRedeem.sol"; + +contract MyScript is Script { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + new NFTBatchRedeem(address(0xC8bBb02015a096F099DedA4eAD138c1Db069cd98)); + + vm.stopBroadcast(); + } +} diff --git a/src/NFT.sol b/src/NFT.sol index a8bf283..efa4ee4 100644 --- a/src/NFT.sol +++ b/src/NFT.sol @@ -26,26 +26,11 @@ contract NFT is ERC721, Ownable { mapping(address => bool) public isWhitelisted; // Event emitted on top of `ERC20::Transfer` for granularity & indexer data availability - event NewTokenData( - uint256 indexed tokenId, - uint256 indexed x_id, - address to, - string policy - ); + event NewTokenData(uint256 indexed tokenId, uint256 indexed x_id, address to, string policy); // Event to be emitted upon redemption of a tweet - event RedeemTweet( - uint256 indexed tokenId, - uint256 indexed x_id, - string policy, - string content - ); + event RedeemTweet(uint256 indexed tokenId, uint256 indexed x_id, string policy, string content); // Event to be emitted upon redemption of a tweet like - event RedeemLike( - uint256 indexed tokenId, - uint256 indexed x_id, - string policy, - string tweetId - ); + event RedeemLike(uint256 indexed tokenId, uint256 indexed x_id, string policy, string tweetId); // Event to be emitted upon whitelisting of a minter event WhitelistMinter(address indexed minter); // Event to be emitted upon removing a minter @@ -54,12 +39,10 @@ contract NFT is ERC721, Ownable { string public baseURI; uint256 public currentTokenId; - constructor( - string memory _name, - string memory _symbol, - string memory _baseURI, - address initialOwner - ) ERC721(_name, _symbol) Ownable(initialOwner) { + constructor(string memory _name, string memory _symbol, string memory _baseURI, address initialOwner) + ERC721(_name, _symbol) + Ownable(initialOwner) + { baseURI = _baseURI; } @@ -73,11 +56,7 @@ contract NFT is ERC721, Ownable { emit RemoveMinter(minter); } - function mintTo( - address recipient, - uint256 x_id, - string memory policy - ) public returns (uint256) { + function mintTo(address recipient, uint256 x_id, string memory policy) public returns (uint256) { require(isWhitelisted[msg.sender], "Caller is not whitelisted"); uint256 newTokenId = ++currentTokenId; _safeMint(recipient, newTokenId); @@ -89,24 +68,15 @@ contract NFT is ERC721, Ownable { return newTokenId; } - function tokenURI( - uint256 tokenId - ) public view override returns (string memory) { + function tokenURI(uint256 tokenId) public view override returns (string memory) { if (ownerOf(tokenId) == address(0)) { revert NonExistentTokenURI(); } - return - bytes(baseURI).length > 0 - ? string.concat(baseURI, tokenId.toString()) - : ""; + return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } // Redeem function that emits an event - function redeem( - uint256 tokenId, - string memory content, - TokenType tokenType - ) public { + function redeem(uint256 tokenId, string memory content, TokenType tokenType) public { require( ownerOf(tokenId) == msg.sender || isWhitelisted[msg.sender], "Caller is not the token owner or the contract owner" diff --git a/src/NFTBatchRedeem.sol b/src/NFTBatchRedeem.sol new file mode 100644 index 0000000..a94e582 --- /dev/null +++ b/src/NFTBatchRedeem.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "./NFT.sol"; + +contract NFTBatchRedeem is ERC721Holder { + NFT nft; + + constructor(address _nft) { + nft = NFT(_nft); + } + + function redeem(uint256[] calldata tokenIds, string memory content) public { + for (uint256 i = 0; i < tokenIds.length; i++) { + nft.redeem(tokenIds[i], content, NFT.TokenType.TWEET); + } + } +}