📄 ProjectManagerStorage.sol
D-OPEN SOVEREIGN
Documentation & Insights
@dev Directly sets a user's balance snapshot. Used by migration scripts only.
Does not enforce authorization — only admin can call.@dev Directly inserts a historical StripeDonation record.
Used by migration scripts to replay donation history into a new contract.1/*
2 * Copyright (c) 2026 DataPond D-Library Pty Ltd. ("The Sanctuary")
3 * Non-Profit Public Library — The World Library
4 *
5 * D-SAFE Certification issued by POND Enterprise.
6 * Published under the D-Open Code Sovereign Licence v1.0 framework
7 * DataPond D-Library All exclusive Right reserved on modifiying the code - CC Attribution to data pond, Non modifiable, Non Commercial.
8 * https://registry.world.bibliotech.com/licence
9 * Source code donated to DataPond D-Library by it's author: data pond.
10 *
11 * Technical Guardian ("The Shield"): Pond Enterprise Pty Ltd. (ACN 694 747 987)
12 * All liability claims about D-SAFE certification issues coming from the published D-Safe direction must be addressed with Pond Enterprise Pty Ltd.
13 * Code Modification automatically voids the certified liability protection provided by Pond Enterprise.
14 */
15
16// SPDX-License-Identifier: Apache-2.0
17pragma solidity ^0.8.24;
18
19import "./IProjectManagerStorage.sol";
20import {ErrorLibrary} from "./ErrorLibrary.sol";
21
22contract ProjectManagerStorage is IProjectManagerStorage {
23 address public admin;
24 mapping(address => bool) public isAuthorized;
25
26 uint16 private _nbProjects;
27 mapping(uint16 => Project) private projects;
28 mapping(uint16 => uint16) private nbLanguages;
29 mapping(uint16 => mapping(bytes4 => uint16)) private availableLanguagesToIndex;
30 mapping(uint16 => mapping(uint16 => bytes4)) private availableLanguagesFromIndex;
31 mapping(uint16 => mapping(bytes4 => mapping(uint16 => Version))) private versions;
32 mapping(uint16 => mapping(bytes4 => uint16)) private nbVersions;
33 mapping(uint16 => mapping(bytes4 => uint256)) private projectVotingBalances;
34 mapping(uint16 => mapping(address => uint256)) private projectDonations;
35 mapping(address => mapping(uint16 => uint256)) private donations;
36 mapping(address => uint256[3]) private balances;
37 mapping(uint256 => StripeDonation[]) private _weeklyDonations;
38
39 modifier onlyAdmin() {
40 require(msg.sender == admin, "not admin");
41 _;
42 }
43
44 modifier onlyAuthorized() {
45 require(isAuthorized[msg.sender] || msg.sender == admin, "not authorized");
46 _;
47 }
48
49 constructor() {
50 admin = msg.sender;
51 }
52
53 function addAuthorized(address caller) external onlyAdmin {
54 isAuthorized[caller] = true;
55 }
56
57 function removeAuthorized(address caller) external onlyAdmin {
58 isAuthorized[caller] = false;
59 }
60
61 // --- Read Methods ---
62 function nbProjects() external view returns (uint16) { return _nbProjects; }
63 function getProject(uint16 projectId) external view returns (uint16 id) { return projects[projectId].id; }
64 function getNbLanguages(uint16 projectId) external view returns (uint16) { return nbLanguages[projectId]; }
65 function getLanguageAtIndex(uint16 projectId, uint16 index) external view returns (bytes4) { return availableLanguagesFromIndex[projectId][index]; }
66 function getLanguageIndex(uint16 projectId, bytes4 lang) external view returns (uint16) { return availableLanguagesToIndex[projectId][lang]; }
67 function getNbVersions(uint16 projectId, bytes4 lang) external view returns (uint16) { return nbVersions[projectId][lang]; }
68 function getVersion(uint16 projectId, bytes4 lang, uint16 versionNumber) external view returns (Version memory) { return versions[projectId][lang][versionNumber]; }
69 function getVotingBalance(uint16 projectId, bytes4 lang) external view returns (uint256) { return projectVotingBalances[projectId][lang]; }
70 function getUserProjectDonation(uint16 projectId, address user) external view returns (uint256) { return projectDonations[projectId][user]; }
71 function getUserTotalDonationForProject(address user, uint16 projectId) external view returns (uint256) { return donations[user][projectId]; }
72 function getUserBalances(address user) external view returns (uint256[3] memory) { return balances[user]; }
73
74 function getWeeklyDonations(uint256 week) external view returns (StripeDonation[] memory) {
75 return _weeklyDonations[week];
76 }
77
78 function getDonationsRange(uint256 fromWeek, uint256 toWeek) external view returns (StripeDonation[] memory) {
79 uint256 totalCount = 0;
80 for (uint256 w = fromWeek; w <= toWeek; w++) {
81 totalCount += _weeklyDonations[w].length;
82 }
83
84 StripeDonation[] memory allDonations = new StripeDonation[](totalCount);
85 uint256 index = 0;
86 for (uint256 w = fromWeek; w <= toWeek; w++) {
87 StripeDonation[] storage weekDonations = _weeklyDonations[w];
88 for (uint256 i = 0; i < weekDonations.length; i++) {
89 allDonations[index] = weekDonations[i];
90 index++;
91 }
92 }
93 return allDonations;
94 }
95
96 // --- Write Methods ---
97 function incrementNbProjects() external onlyAuthorized returns (uint16) {
98 _nbProjects++;
99 return _nbProjects;
100 }
101
102 function setProject(uint16 projectId) external onlyAuthorized {
103 projects[projectId] = Project(projectId);
104 }
105
106 function setNbLanguages(uint16 projectId, uint16 count) external onlyAuthorized {
107 nbLanguages[projectId] = count;
108 }
109
110 function setLanguageMapping(uint16 projectId, bytes4 lang, uint16 index) external onlyAuthorized {
111 availableLanguagesToIndex[projectId][lang] = index;
112 availableLanguagesFromIndex[projectId][index] = lang;
113 }
114
115 function setNbVersions(uint16 projectId, bytes4 lang, uint16 count) external onlyAuthorized {
116 nbVersions[projectId][lang] = count;
117 }
118
119 function setVersion(uint16 projectId, bytes4 lang, uint16 versionNumber, Version calldata version) external onlyAuthorized {
120 versions[projectId][lang][versionNumber] = version;
121 }
122
123 function updateVotingBalance(uint16 projectId, bytes4 lang, uint256 amount, bool add) external onlyAuthorized {
124 if (add) projectVotingBalances[projectId][lang] += amount;
125 else projectVotingBalances[projectId][lang] -= amount;
126 }
127
128 function updateUserProjectDonation(uint16 projectId, address user, uint256 amount, bool add) external onlyAuthorized {
129 if (add) projectDonations[projectId][user] += amount;
130 else projectDonations[projectId][user] -= amount;
131 }
132
133 function updateUserTotalDonationForProject(address user, uint16 projectId, uint256 amount, bool add) external onlyAuthorized {
134 if (add) donations[user][projectId] += amount;
135 else donations[user][projectId] -= amount;
136 }
137
138 function updateUserBalances(address user, uint256[3] calldata newBalances) external onlyAuthorized {
139 balances[user] = newBalances;
140 }
141
142 function recordStripeDonation(uint256 week, StripeDonation calldata donation) external onlyAuthorized {
143 _weeklyDonations[week].push(donation);
144 }
145
146 // ===== Admin bulk-import (migration scripts only) =====
147
148 /**
149 * @dev Directly sets a user's balance snapshot. Used by migration scripts only.
150 * Does not enforce authorization — only admin can call.
151 */
152 function importUserBalances(address user, uint256[3] calldata bals) external onlyAdmin {
153 require(user != address(0), "zero addr");
154 balances[user] = bals;
155 }
156
157 /**
158 * @dev Directly inserts a historical StripeDonation record.
159 * Used by migration scripts to replay donation history into a new contract.
160 */
161 function importStripeDonation(uint256 week, StripeDonation calldata donation) external onlyAdmin {
162 _weeklyDonations[week].push(donation);
163 }
164}