forked from estarriolvetch/ERC721Psi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds ERC721PsiUpgradeable with passing tests
- Loading branch information
Nidhhoggr
committed
Dec 26, 2022
1 parent
b9a3508
commit 062dbec
Showing
18 changed files
with
596 additions
and
563 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/** | ||
* @dev This is a base contract to aid in writing upgradeable diamond facet contracts, or any kind of contract that will be deployed | ||
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an | ||
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer | ||
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. | ||
* | ||
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as | ||
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. | ||
* | ||
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure | ||
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. | ||
*/ | ||
|
||
import {ERC721PsiInitializableStorage} from './ERC721PsiInitializableStorage.sol'; | ||
|
||
abstract contract ERC721PsiInitializable { | ||
using ERC721PsiInitializableStorage for ERC721PsiInitializableStorage.Layout; | ||
|
||
/** | ||
* @dev Modifier to protect an initializer function from being invoked twice. | ||
*/ | ||
modifier initializerERC721Psi() { | ||
// If the contract is initializing we ignore whether _initialized is set in order to support multiple | ||
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the | ||
// contract may have been reentered. | ||
require( | ||
ERC721PsiInitializableStorage.layout()._initializing | ||
? _isConstructor() | ||
: !ERC721PsiInitializableStorage.layout()._initialized, | ||
'ERC721Psi__Initializable: contract is already initialized' | ||
); | ||
|
||
bool isTopLevelCall = !ERC721PsiInitializableStorage.layout()._initializing; | ||
if (isTopLevelCall) { | ||
ERC721PsiInitializableStorage.layout()._initializing = true; | ||
ERC721PsiInitializableStorage.layout()._initialized = true; | ||
} | ||
|
||
_; | ||
|
||
if (isTopLevelCall) { | ||
ERC721PsiInitializableStorage.layout()._initializing = false; | ||
} | ||
} | ||
|
||
/** | ||
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the | ||
* {initializer} modifier, directly or indirectly. | ||
*/ | ||
modifier onlyInitializingERC721Psi() { | ||
require( | ||
ERC721PsiInitializableStorage.layout()._initializing, | ||
'ERC721PsiInitializable: contract is not initializing' | ||
); | ||
_; | ||
} | ||
|
||
/// @dev Returns true if and only if the function is running in the constructor | ||
function _isConstructor() private view returns (bool) { | ||
// extcodesize checks the size of the code stored in an address, and | ||
// address returns the current address. Since the code is still not | ||
// deployed when running a constructor, any checks on its code size will | ||
// yield zero, making it an effective way to detect if a contract is | ||
// under construction or not. | ||
address self = address(this); | ||
uint256 cs; | ||
assembly { | ||
cs := extcodesize(self) | ||
} | ||
return cs == 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
/** | ||
* @dev This is a base storage for the initialization function for upgradeable diamond facet contracts | ||
**/ | ||
|
||
library ERC721PsiInitializableStorage { | ||
struct Layout { | ||
/* | ||
* Indicates that the contract has been initialized. | ||
*/ | ||
bool _initialized; | ||
/* | ||
* Indicates that the contract is in the process of being initialized. | ||
*/ | ||
bool _initializing; | ||
} | ||
|
||
bytes32 internal constant STORAGE_SLOT = keccak256('ERC721Psi.contracts.storage.initializable.facet'); | ||
|
||
function layout() internal pure returns (Layout storage l) { | ||
bytes32 slot = STORAGE_SLOT; | ||
assembly { | ||
l.slot := slot | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import "solidity-bits/contracts/BitMaps.sol"; | ||
|
||
library ERC721PsiStorage { | ||
|
||
|
||
|
||
struct Layout { | ||
// ============================================================= | ||
// STORAGE | ||
// ============================================================= | ||
|
||
// The next token ID to be minted. | ||
uint256 _currentIndex; | ||
// The number of tokens burned. | ||
uint256 _burnCounter; | ||
// Token name | ||
string _name; | ||
// Token symbol | ||
string _symbol; | ||
// Mapping from token ID to owner address | ||
mapping(uint256 => address) _owners; | ||
// Mapping from token ID to approved address. | ||
mapping(uint256 => address) _tokenApprovals; | ||
// Mapping from owner to operator approvals | ||
mapping(address => mapping(address => bool)) _operatorApprovals; | ||
// stores batchhead | ||
BitMaps.BitMap _batchHead; | ||
} | ||
|
||
bytes32 internal constant STORAGE_SLOT = keccak256('ERC721Psi.contracts.storage.ERC721A'); | ||
|
||
function layout() internal pure returns (Layout storage l) { | ||
bytes32 slot = STORAGE_SLOT; | ||
assembly { | ||
l.slot := slot | ||
} | ||
} | ||
} |
Oops, something went wrong.