-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1.updateERC721.js
189 lines (158 loc) · 6 KB
/
1.updateERC721.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
const fs = require("fs");
const path = require("path");
// Path to the existing contract
const contractPath = path.join(__dirname, "../contracts/NFTFactory.sol");
// Read the existing contract
let contractContent = fs.readFileSync(contractPath, "utf8");
// Define the new storage and functions to be added
const newStorage = `
struct Nft {
uint256 tokenId;
uint256 value; // 27 decimals
string tokenURI; // IPFS address of the metadata file
}
Nft[] public Nfts;
// Contract addresses
address internal wston;
address internal treasury;
// events
event Created(uint256 indexed tokenId, uint256 value, address owner, string tokenURI);
event NFTBurnt(uint256 indexed tokenId, address owner);
//errors
error UnauthorizedCaller(address caller);
`;
const newFunctions = `
/**
* @notice Modifier to ensure the caller is the treasury contract
*/
modifier onlyTreasury() {
if (msg.sender != treasury) {
revert UnauthorizedCaller(msg.sender);
}
_;
}
/**
* @notice Sets the treasury address.
* @param _treasury The new treasury address.
*/
function setTreasury(address _treasury) external onlyOwner {
treasury = _treasury;
}
/**
* @notice Updates the wston token address.
* @param _wston New wston token address.
*/
function setWston(address _wston) external onlyOwner {
wston = _wston;
}
/**
* @notice Burns an NFT, converting it back to its value.
* @param _tokenId ID of the token to burn.
* @dev The caller receives the WSTON amount associated with the NFT.
* @dev The ERC721 token is burned.
* @dev The caller must be the token owner.
*/
function burnNFT(uint256 _tokenId) external {
require(msg.sender != address(0), "AddressZero");
require(ownerOf(_tokenId) == msg.sender, "NotNFTOwner");
uint256 amount = Nfts[_tokenId].value;
delete Nfts[_tokenId];
_burn(_tokenId);
require(ITreasury(treasury).transferWSTON(msg.sender, amount), "TransferFailed");
emit NFTBurnt(_tokenId, msg.sender);
}
/**
* @notice Creates an NFT based on its attributes passed in the parameters and assigns their ownership to the owner.
* @param _value WSTON value of the new NFT to be created.
* @param _owner Owner of the new NFT.
* @param _tokenURI TokenURI of the NFT.
* @return The ID of the newly created NFT.
*/
function createNFT(uint256 _value, address _owner, string memory _tokenURI)
public
onlyTreasury
returns (uint256)
{
require(_owner != address(0), "AddressZero");
uint256 newNftId = Nfts.length;
Nfts.push(Nft({
tokenId: newNftId,
value: _value,
tokenURI: _tokenURI
}));
_safeMint(_owner, newNftId);
emit Created(newNftId, _value, _owner, _tokenURI);
return newNftId;
}
/**
* @notice Creates a pool of NFTs based on their attributes passed in the parameters and assigns their ownership to the owners.
* @param _values Value of each NFT to be minted.
* @param _owners Owners of the NFTs to be minted.
* @param _tokenURIs TokenURIs of each NFT.
* @return The IDs of the newly created NFTs.
*/
function createNFTPool(
uint256[] memory _values,
address[] memory _owners,
string[] memory _tokenURIs
) public onlyTreasury returns (uint256[] memory) {
require(_values.length == _owners.length && _values.length == _tokenURIs.length, "Wrong parameters length");
uint256[] memory newNftIds = new uint256[](_values.length);
for (uint256 i = 0; i < _values.length; i++) {
newNftIds[i] = createNFT(_values[i], _owners[i], _tokenURIs[i]);
}
return newNftIds;
}
/**
* @notice Handles the receipt of an ERC721 token.
* @return bytes4 Returns the selector of the onERC721Received function.
*/
function onERC721Received(
address /*operator*/,
address /*from*/,
uint256 /*tokenId*/,
bytes calldata /*data*/
) external pure returns (bytes4) {
return this.onERC721Received.selector;
}
`;
// Define the new imports and interfaces
const newImports = `
import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
`;
const newInterfaces = `
interface ITreasury {
function transferWSTON(address recipient, uint256 amount) external returns (bool);
}
`;
// Inject new imports after the existing imports
contractContent = contractContent.replace(
/import "@openzeppelin\/contracts\/token\/ERC721\/ERC721.sol";/,
`import "@openzeppelin/contracts/token/ERC721/ERC721.sol";`
);
// Extract the contract declaration line
const contractDeclarationRegex = /contract\s+(\w+)\s+is\s+([^{]+)\s*{/;
const contractDeclarationMatch = contractContent.match(contractDeclarationRegex);
if (contractDeclarationMatch) {
const contractName = contractDeclarationMatch[1];
const existingInheritance = contractDeclarationMatch[2];
// Modify the contract declaration to include new inheritance and storage
const updatedContractDeclaration = `${newImports}\n${newInterfaces}\ncontract ${contractName} is ${existingInheritance}, IERC721Receiver {${newStorage}`;
// Replace the old contract declaration with the updated one
contractContent = contractContent.replace(
contractDeclarationRegex,
updatedContractDeclaration
);
} else {
console.error("Could not find the contract declaration in the source file.");
process.exit(1);
}
// Inject new interfaces and functions before the last closing brace
contractContent = contractContent.replace(
/}\s*$/,
`${newFunctions}\n}`
);
// Write the updated contract to a new file
const updatedContractPath = path.join(__dirname, "../contracts/UpdatedNFTFactory.sol");
fs.writeFileSync(updatedContractPath, contractContent);
console.log("Contract updated and saved to UpdatedGameItem.sol");