//SPDX-License-Identifier: MIT import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; pragma solidity ^0.8.5; /************************************** CONTRACT **************************************/ interface IRoles { function isManager(address account) external view returns(bool); function isAsstManager(address account) external view returns(bool); function isPauser(address account) external view returns(bool); } interface IAddressSmartContract { function getRolesContractAddress() external view returns (address); } contract RegistryPart1 is Initializable, UUPSUpgradeable, AccessControlUpgradeable, PausableUpgradeable, OwnableUpgradeable { address private addressSC; function initialize( address AddressSmartContract) public initializer { addressSC = AddressSmartContract; __AccessControl_init(); __Pausable_init(); __Ownable_init(); } function _authorizeUpgrade(address) internal virtual override onlyOwner {} /************************************** STRUCTURES **************************************/ //TABLE STRUCTURE struct LLD_Data { bytes32 lld; bytes32 projectId; bytes32 creditType; uint256 year; uint256 numberOfCarbonCredits; uint256 reservedCredits; uint256 reservedCreditsUsed; bool isValued; bool isReleased; } mapping (bytes32 => LLD_Data) public lookUpTable; function stringToBytes32(string memory _str) public pure returns (bytes32) { bytes memory tempBytes = bytes(_str); bytes32 convertedBytes; if(tempBytes.length == 0){ return 0x0; } assembly{ convertedBytes := mload(add(_str,32)) } return convertedBytes; } //----------------------- REGISTER NEW LLD FUNCTIONS -----------------------// //MAKE A NEW ENTRY IN THE TABLE function registerLLD ( string memory LLD, string memory ProjectId, string memory CreditType, uint256 Year, uint256 NumberOfCarbonCredits, uint256 ReservedCredits, uint256 ReservedCreditsUsed ) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isManager(msg.sender), "Access Denied: Caller is NOT Manager!"); require(!getIsValued(LLD,CreditType,Year), "Duplicate LLD: The LLD is already registered with Registry!"); bytes32 newEntry = keccak256(abi.encodePacked(LLD,CreditType,Year)); lookUpTable[newEntry].lld = stringToBytes32(LLD); lookUpTable[newEntry].projectId = stringToBytes32(ProjectId); lookUpTable[newEntry].creditType = stringToBytes32(CreditType); lookUpTable[newEntry].year = Year; lookUpTable[newEntry].numberOfCarbonCredits = NumberOfCarbonCredits; lookUpTable[newEntry].reservedCredits = ReservedCredits; lookUpTable[newEntry].reservedCreditsUsed = ReservedCreditsUsed; lookUpTable[newEntry].isValued = true; lookUpTable[newEntry].isReleased = false; } //GET NumberOfCarbonCredits function getNumberOfCarbonCredits(string memory LLD, string memory CreditType, uint256 Year) public view returns (uint256) { require(getIsValued(LLD, CreditType, Year), "Error: Input LLD not found in Registry!"); return lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].numberOfCarbonCredits; } //GET isValued STATUS function getIsValued(string memory LLD, string memory CreditType, uint256 Year) public view returns (bool) { if (lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].isValued) return true; else return false; } function getIsReleased(string memory LLD, string memory CreditType, uint256 Year) public view returns (bool) { require(getIsValued(LLD, CreditType, Year), "Error: Input LLD not found in Registry!"); return lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].isReleased; } //GET ALL FIELDS function getLLDFields(string memory LLD, string memory CreditType, uint256 Year) public view returns ( string memory ProjectId, uint256 NumberOfCarbonCredits, uint256 ReservedCredits, uint256 ReservedCreditsUsed, bool IsReleased) { require(getIsValued(LLD,CreditType,Year), "Error: Input LLD not found in Registry!"); return ( string(abi.encodePacked(lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].projectId)), getNumberOfCarbonCredits(LLD,CreditType,Year), lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].reservedCredits, lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].reservedCreditsUsed, getIsReleased(LLD,CreditType,Year) ); } //-----------------UPDATE REQUIRED FIELDS FUNCTIONS ----------------// function updateAddressSmartContract(address AddressSmartContract) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isManager(msg.sender), "Access Denied: Caller is NOT Manager!"); require(AddressSmartContract != address(0), "Account: Zero or Invalid address!"); addressSC = AddressSmartContract; } //UPDATE LLD/CreditType/Year function updateLLD(string memory oldLLD, string memory oldCreditType, uint256 oldYear, string memory newLLD, string memory newCreditType, uint256 newYear) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isManager(msg.sender), "Access Denied: Caller is NOT Manager!"); require(getIsValued(oldLLD, oldCreditType, oldYear), "Error: Input LLD not found in Registry!"); require(!getIsValued(newLLD,newCreditType,newYear), "Error: Input NEW LLD values are already registered with Registry!"); require(!(keccak256(abi.encodePacked(newLLD)) == keccak256(abi.encodePacked(""))), "Invalid input: Zero or invalid LLD!"); require(!(keccak256(abi.encodePacked(newCreditType)) == keccak256(abi.encodePacked(""))), "Invalid input: Zero or invalid CreditType!"); require(!(newYear == 0), "Invalid input: Zero or invalid year!"); bytes32 oldEntry = keccak256(abi.encodePacked(oldLLD,oldCreditType,oldYear)); bytes32 newEntry = keccak256(abi.encodePacked(newLLD,newCreditType,newYear)); lookUpTable[newEntry].lld = stringToBytes32(newLLD); lookUpTable[newEntry].projectId = lookUpTable[oldEntry].projectId; lookUpTable[newEntry].creditType = stringToBytes32(newCreditType); lookUpTable[newEntry].year = newYear; lookUpTable[newEntry].numberOfCarbonCredits = getNumberOfCarbonCredits(oldLLD,oldCreditType,oldYear); lookUpTable[newEntry].reservedCredits = lookUpTable[oldEntry].reservedCredits; lookUpTable[newEntry].reservedCreditsUsed = lookUpTable[oldEntry].reservedCreditsUsed; lookUpTable[newEntry].isValued = true; lookUpTable[newEntry].isReleased = getIsReleased(oldLLD,oldCreditType,oldYear); deleteLLD(oldLLD, oldCreditType, oldYear); } //UPDATE ProjectId function updateProjectId(string memory LLD, string memory CreditType, uint256 Year, string memory NewProjectId) whenNotPaused public { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isAsstManager(msg.sender), "Access Denied: Caller is NOT Assistant Manager!"); require(getIsValued(LLD,CreditType,Year), "Error: Input LLD not found in Registry!"); lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].projectId = stringToBytes32(NewProjectId); } //UPDATE numberOfCarbonCredits function updateNumberOfCarbonCredits(string memory LLD, string memory CreditType, uint256 Year, uint256 NewNumberOfCarbonCredits) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isAsstManager(msg.sender), "Access Denied: Caller is NOT Assistant Manager!"); require(getIsValued(LLD,CreditType,Year), "Error: Input LLD not found in Registry!"); lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].numberOfCarbonCredits = NewNumberOfCarbonCredits; } //UPDATE reserveredCredits function updateReservedCredits(string memory LLD, string memory CreditType, uint256 Year, uint256 NewReservedCredits) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isAsstManager(msg.sender), "Access Denied: Caller is NOT Assistant Manager!"); require(getIsValued(LLD,CreditType,Year), "Error: Input LLD not found in Registry!"); lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].reservedCredits = NewReservedCredits; } //UPDATE reserveredCreditsUsed function updateReservedCreditsUsed(string memory LLD, string memory CreditType, uint256 Year, uint256 NewReservedCreditsUsed) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isAsstManager(msg.sender), "Access Denied: Caller is NOT Assistant Manager!"); require(getIsValued(LLD,CreditType,Year), "Error: Input LLD not found in Registry!"); lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].reservedCreditsUsed = NewReservedCreditsUsed; } //UPDATE isReleased function updateIsReleased(string memory LLD, string memory CreditType, uint256 Year, bool IsReleased) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isAsstManager(msg.sender), "Access Denied: Caller is NOT Assistant Manager!"); require(getIsValued(LLD, CreditType, Year), "Error: Input LLD not found in Registry!"); lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))].isReleased = IsReleased; } //----------------------- PAUSER FUNCTIONS -----------------------// function pauseContract() public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isPauser(msg.sender), "Access Denied: Caller is NOT Pauser!"); _pause(); } function unPauseContract() public whenPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isPauser(msg.sender), "Access Denied: Caller is NOT Pauser!"); _unpause(); } //----------------------- KILL FUNCTIONS -----------------------// //DELETE A LLD ENTRY function deleteLLD(string memory LLD, string memory CreditType, uint256 Year) public whenNotPaused { require(IRoles(IAddressSmartContract(addressSC).getRolesContractAddress()).isManager(msg.sender), "Access Denied: Caller is NOT Manager!"); require(getIsValued(LLD,CreditType,Year), "Error: Input LLD not found with Registry!"); delete lookUpTable[keccak256(abi.encodePacked(LLD,CreditType,Year))]; } }