200 | )
201 | }
202 |
203 | export default CampaignDetails
--------------------------------------------------------------------------------
/client/LICENSE.md:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2021 Non-Fungible Labs, Inc
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/web3.0/contracts/CrowdFunding.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.19;
3 | import "@openzeppelin/contracts/access/Ownable.sol";
4 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
5 | // To use circuit-breaker pattern from oz-contracts, can use:
6 | // import "@openzeppelin/contracts/security/Pausable.sol";
7 | // (As a tradeoff, I decided to just implement my simple circuit-breaker for gas efficiency)
8 | // Todo: import {CampaignTypes} from "./CampaignTypes.sol";
9 |
10 | /// @title The crowdfunding platform
11 | /// @author Bahador Ghadamkheir
12 | /// @dev This is a sample crowdfunding smart contract.
13 | /// @notice As this contract is not audited, use at your own risk!
14 | contract CrowdFunding is Ownable {
15 | using SafeMath for uint256;
16 |
17 | /// Strcuture of each campaign
18 | struct Campaign {
19 | address owner;
20 | bool payedOut;
21 | string title;
22 | string description;
23 | uint256 target;
24 | uint256 deadline;
25 | uint256 amountCollected;
26 | string image;
27 | address[] donators;
28 | uint256[] donations;
29 | }
30 |
31 | // a mapppig to hold each campaign's data
32 | mapping(uint256 => Campaign) public campaigns;
33 |
34 | // defining tax of the platform
35 | uint8 public platformTax;
36 | // holding number of all campaigns
37 | uint24 public numberOfCampaigns;
38 |
39 | // avtivity status of the contract
40 | bool public emergencyMode; // default: false
41 |
42 | // Will be emitted when a main functionality executed
43 | // (such as: creating/deleting/updating capaigns, and etc.)
44 | event Action (
45 | uint256 id,
46 | string actionType,
47 | address indexed executor,
48 | uint256 timestamp
49 | );
50 |
51 | // Will be emitted in case of changing activity status of the contract
52 | event ContractStateChanged (
53 | bool State
54 | );
55 |
56 | /// Will arise when msg.value is lower than minAmount
57 | /// `minAmount` minimmum amount
58 | /// @param minAmount the minnimum acceptable ETH amount to fund
59 | /// @param payedAmount the ETH amount funded by user
60 | error LowEtherAmount(uint minAmount, uint payedAmount);
61 |
62 | /// Will arise when block.timestamp is more than campaingDeadline
63 | /// `campaingDeadline` deadline
64 | /// @param campaingDeadline deadline time of fundraising the campaign
65 | /// @param requestTime time of requesting
66 | error DeadLine(uint campaingDeadline, uint requestTime);
67 |
68 | // Preventing unauthorized entity execute specific function
69 | modifier privilageEntity(uint _id) {
70 | _privilagedEntity(_id);
71 | _;
72 | }
73 |
74 | // To have an scape way when something bad happened in contract
75 | modifier notInEmergency() {
76 | require(!emergencyMode);
77 | _;
78 | }
79 |
80 | // To have an scape way when something bad happened in contract
81 | modifier onlyInEmergency() {
82 | require(emergencyMode);
83 | _;
84 | }
85 |
86 | // Preventing entering null values as campaign details
87 | modifier notNull(
88 | string memory title,
89 | string memory description,
90 | uint256 target,
91 | uint256 deadline,
92 | string memory image) {
93 | _nullChecker(title, description, target, deadline, image);
94 | _;
95 | }
96 |
97 | /// @param _platformTax initilizing tax of the platform
98 | constructor(uint8 _platformTax) {
99 | platformTax = _platformTax;
100 | }
101 |
102 | /** @notice Create a fundraising campaign
103 | * @param _owner creator of the fundraising campaign
104 | * @param _title title of the fundraising campaign
105 | * @param _description description of the fundraising campaign
106 | * @param _target desired ETH target amount of the fundraising campaign(based on wei)
107 | * @param _deadline deadline of the fundraising campaign
108 | * @param _image image address of the fundraising campaign
109 | * @return campaign id
110 | */
111 | function createCampaign(
112 | address _owner,
113 | string memory _title,
114 | string memory _description,
115 | uint256 _target,
116 | uint256 _deadline,
117 | string memory _image
118 | ) external notNull(_title, _description, _target, _deadline, _image) notInEmergency returns (uint256) {
119 | require(block.timestamp < _deadline, "Deadline must be in the future");
120 | Campaign storage campaign = campaigns[numberOfCampaigns];
121 | numberOfCampaigns++;
122 |
123 | campaign.owner = _owner;
124 | campaign.title = _title;
125 | campaign.description = _description;
126 | campaign.target = _target;
127 | campaign.deadline = _deadline;
128 | campaign.amountCollected = 0;
129 | campaign.image = _image;
130 | campaign.payedOut = false;
131 |
132 | emit Action (
133 | numberOfCampaigns,
134 | "Campaign Created",
135 | msg.sender,
136 | block.timestamp
137 | );
138 |
139 | return numberOfCampaigns - 1;
140 | }
141 |
142 | /** @notice Update a fundraising campaign
143 | * @param _id campign id
144 | * @param _title new title of the fundraising campaign
145 | * @param _description new description of the fundraising campaign
146 | * @param _target new desired ETH target amount of the fundraising campaign(based on wei)
147 | * @param _deadline new deadline of the fundraising campaign
148 | * @param _image new image address of the fundraising campaign
149 | * @return status of campaign update request
150 | */
151 | function updateCampaign(
152 | uint256 _id,
153 | string memory _title,
154 | string memory _description,
155 | uint256 _target,
156 | uint256 _deadline,
157 | string memory _image
158 | ) external privilageEntity(_id) notNull(_title, _description, _target, _deadline, _image) notInEmergency returns (bool) {
159 | require(block.timestamp < _deadline, "Deadline must be in the future");
160 |
161 | // Making a pointer for a campaign
162 | Campaign storage campaign = campaigns[_id];
163 | require(campaign.owner > address(0), "No campaign exist with this ID");
164 | require(campaign.amountCollected == 0, "Update error: amount collected");
165 |
166 | campaign.title = _title;
167 | campaign.description = _description;
168 | campaign.target = _target;
169 | campaign.deadline = _deadline;
170 | campaign.amountCollected = 0;
171 | campaign.image = _image;
172 | campaign.payedOut = false;
173 |
174 | emit Action (
175 | _id,
176 | "Campaign Updated",
177 | msg.sender,
178 | block.timestamp
179 | );
180 | return true;
181 | }
182 |
183 | /// @notice Donate to an specific fundraising campaign
184 | /// @param _id campaign id
185 | function donateToCampaign(uint256 _id) external payable notInEmergency {
186 | if(msg.value == 0 wei) revert LowEtherAmount({minAmount: 1 wei, payedAmount: msg.value});
187 | Campaign storage campaign = campaigns[_id];
188 | if(campaigns[_id].payedOut == true) revert("Funds withdrawed before");
189 | require(campaign.owner > address(0), "No campaign exist with this ID");
190 | if(campaign.deadline < block.timestamp) {
191 | revert DeadLine(
192 | {
193 | campaingDeadline:campaigns[_id].deadline,
194 | requestTime: block.timestamp
195 | }
196 | );
197 | }
198 | uint256 amount = msg.value;
199 | if(campaign.amountCollected > campaign.amountCollected.add(amount)) revert ("Target amount has reached");
200 | campaign.amountCollected = campaign.amountCollected.add(amount);
201 |
202 | campaign.donators.push(msg.sender);
203 | campaign.donations.push(amount);
204 |
205 | emit Action (
206 | _id,
207 | "Donation To The Campaign",
208 | msg.sender,
209 | block.timestamp
210 | );
211 | }
212 |
213 | /// @notice Transfering raised funds to the campaign team
214 | /// @param _id campaign id
215 | /// @return true, if payout process get completely done
216 | function payOutToCampaignTeam(uint256 _id) external privilageEntity(_id) notInEmergency returns (bool) {
217 | // this line will avoid re-entrancy attack
218 | if(campaigns[_id].payedOut == true) revert("Funds withdrawed before");
219 | if(msg.sender != address(owner())) {
220 | if(campaigns[_id].deadline > block.timestamp) {
221 | revert DeadLine(
222 | {
223 | campaingDeadline:campaigns[_id].deadline,
224 | requestTime: block.timestamp
225 | }
226 | );
227 | }
228 | }
229 |
230 | campaigns[_id].payedOut = true;
231 | (uint256 raisedAmount, uint256 taxAmount) = _calculateTax(_id);
232 | _payTo(campaigns[_id].owner, (raisedAmount - taxAmount));
233 | _payPlatformFee(taxAmount);
234 | emit Action (
235 | _id,
236 | "Funds Withdrawal",
237 | msg.sender,
238 | block.timestamp
239 | );
240 | return true;
241 | }
242 |
243 | /// @notice Paying platform fee
244 | /// @param _taxAmount tax amount to transfer into platform owner account
245 | function _payPlatformFee(uint256 _taxAmount) internal {
246 | _payTo(owner(), _taxAmount);
247 | }
248 |
249 | /// @notice Deleting a specific fundraising campaign
250 | /// @param _id campaign id
251 | /// @return true, if deleting be correctly done
252 | function deleteCampaign(uint256 _id) external privilageEntity(_id) notInEmergency returns (bool) {
253 | // to check if a capmpaign with specific id exists.
254 | require(campaigns[_id].owner > address(0), "No campaign exist with this ID");
255 | if(campaigns[_id].amountCollected > 0 wei) {
256 | _refundDonators(_id);
257 | }
258 | delete campaigns[_id];
259 |
260 | emit Action (
261 | _id,
262 | "Campaign Deleted",
263 | msg.sender,
264 | block.timestamp
265 | );
266 |
267 | numberOfCampaigns -= 1;
268 | return true;
269 | }
270 |
271 | /// @notice Showing donators of a specific campaign
272 | /// @param _id campaign id
273 | /// @return donator's addresses
274 | /// @return donator's funded amount
275 | function getDonators(uint256 _id) external view returns (address[] memory, uint256[] memory) {
276 | return (campaigns[_id].donators, campaigns[_id].donations);
277 | }
278 |
279 | /// @notice Updating platform tax
280 | /// @param _platformTax new platform tax
281 | function changeTax(uint8 _platformTax) external onlyOwner {
282 | platformTax = _platformTax;
283 | }
284 |
285 | /// @notice Halting fundraising of a specific campaign
286 | /// @param _id campaign id
287 | function haltCampaign(uint256 _id) external onlyOwner {
288 | campaigns[_id].deadline = block.timestamp;
289 |
290 | emit Action (
291 | _id,
292 | "Campaign halted",
293 | msg.sender,
294 | block.timestamp
295 | );
296 | }
297 |
298 | /** @notice Showing all campaigns data
299 | * @dev todo: making slicing for pagination,
300 | * @dev to reduce the chance of reverting(exceeding block gas limit) in case of big number of campaigns.
301 | * @dev getCampaigns(uint256 startIndex, uint256 endIndex)
302 | * @return campaigns data
303 | */
304 | function getCampaigns() external view returns (Campaign[] memory) {
305 | Campaign[] memory allCampaigns = new Campaign[](numberOfCampaigns);
306 |
307 | for(uint i=0; i < numberOfCampaigns; i++) {
308 | Campaign storage item = campaigns[i];
309 |
310 | allCampaigns[i] = item;
311 | }
312 | return allCampaigns;
313 | }
314 |
315 | /// @notice Changing activity status of the contract
316 | /// @dev implemented mainly for any unintended situation which risks campaigns funds
317 | function changeContractState() external onlyOwner {
318 | emergencyMode = !emergencyMode;
319 |
320 | emit ContractStateChanged(emergencyMode);
321 | }
322 |
323 | /// @notice Withdrawing funds and refunding to donators, in case of an emergency situation(such as bugs, hacks, etc)
324 | /// @param _startId id of first campaign to refund
325 | /// @param _endId id of end campaign to refund
326 | function withdrawFunds(uint256 _startId, uint256 _endId) external onlyOwner onlyInEmergency {
327 | for(uint i = _startId; i <= _endId; i++) {
328 | _refundDonators(_startId, _endId);
329 | }
330 | }
331 |
332 | /// @notice Making refund to donators of a specific campaign
333 | /// @param _id campgin id
334 | function _refundDonators(uint _id) internal {
335 | uint256 donationAmount;
336 | Campaign storage campaign = campaigns[_id];
337 | for(uint i; i < campaign.donators.length; i++) {
338 | donationAmount = campaign.donations[i];
339 | campaign.donations[i] = 0;
340 | _payTo(campaign.donators[i], donationAmount);
341 | // campaign.donations[i] = 0;
342 | }
343 | campaign.amountCollected = 0;
344 | }
345 |
346 | /// @notice Making refund to donators of specific campaigns range
347 | /// @param _idFrom campgin id from
348 | /// @param _idTo campgin id to
349 | function _refundDonators(uint256 _idFrom, uint256 _idTo) internal {
350 | require(_idFrom < _idTo, "Invalid id range");
351 | require(campaigns[_idTo].owner > address(0), "No campaign exist with this ID");
352 | uint256 donationAmount;
353 | for(uint i = _idFrom; i < _idTo; i++) {
354 | Campaign storage campaign = campaigns[i];
355 | uint256 campaignDonators = campaign.donators.length;
356 | if(campaignDonators > 0) {
357 | for(uint j = 0; j < campaignDonators; j++) {
358 | donationAmount = campaign.donations[j];
359 | campaign.donations[j] = 0;
360 | _payTo(campaign.donators[j], donationAmount);
361 | // campaign.donations[j] = 0;
362 | }
363 | campaign.amountCollected = 0;
364 | }
365 | }
366 | }
367 |
368 | /// @notice Calculating the tax amount
369 | /// @param _id campaign id
370 | /// @return total funded amount of specific campaign
371 | /// @return tax amount of funded amount of specific campaign
372 | function _calculateTax(uint256 _id) internal view returns (uint, uint) {
373 | uint raised = campaigns[_id].amountCollected;
374 | uint tax = (raised * platformTax) / 100;
375 | return (raised, tax);
376 | }
377 |
378 | /// @notice Paying stakeholders of the campaign(campaign creator & platform owner)
379 | /// @param to recipient of the raised amount
380 | /// @param amount raised amount
381 | function _payTo(address to, uint256 amount) internal returns (bool) {
382 | (bool success, ) = payable(to).call{value: amount}("");
383 | require(success);
384 | return true;
385 | }
386 |
387 | /** @notice Preventing entering null values as campaign details
388 | * @param _title title of the fundraising campaign
389 | * @param _description description of the fundraising campaign
390 | * @param _target desired ETH target amount of the fundraising campaign(based on wei)
391 | * @param _deadline deadline of the fundraising campaign
392 | * @param _image image address of the fundraising campaign
393 | */
394 | function _nullChecker(
395 | string memory _title,
396 | string memory _description,
397 | uint256 _target,
398 | uint256 _deadline,
399 | string memory _image
400 | ) internal pure {
401 | require((
402 | bytes(_title).length > 0
403 | && bytes(_description).length > 0
404 | && _target > 0
405 | && _deadline > 0
406 | && bytes(_image).length > 0
407 | ), "Null value not acceptable");
408 | }
409 |
410 | /// @notice Preventing unauthorized entity to execute specific function
411 | /// @param _id campaign id
412 | function _privilagedEntity(uint256 _id) internal view {
413 | require(
414 | msg.sender == campaigns[_id].owner ||
415 | msg.sender == owner(),
416 | "Unauthorized Entity"
417 | );
418 | }
419 | }
--------------------------------------------------------------------------------