├── .husky └── pre-commit ├── lib ├── hardhat.config.ts ├── tsconfig.json ├── index.ts ├── mocha_describe_filter.ts ├── README.md ├── bigint_conversion.ts ├── storage_layout.ts ├── sign_data.ts └── package.json ├── .mocharc.json ├── spec ├── hardhat.config.ts ├── tsconfig.json ├── proxy │ └── beacon │ │ ├── BeaconProxy.behavior.ts │ │ └── diamond │ │ └── DiamondBeaconProxy.behavior.ts ├── access │ ├── pausable │ │ └── Pausable.behavior.ts │ └── partially_pausable │ │ └── PartiallyPausable.behavior.ts ├── token │ ├── multi │ │ ├── metadata │ │ │ └── MultiTokenMetadata.behavior.ts │ │ └── SolidstateMultiToken.behavior.ts │ ├── fungible │ │ ├── SolidstateFungibleToken.behavior.ts │ │ └── metadata │ │ │ └── FungibleTokenMetadata.behavior.ts │ └── non_fungible │ │ └── metadata │ │ └── NonFungibleTokenMetadata.behavior.ts ├── package.json ├── signature │ └── contract_signer │ │ └── ContractSigner.behavior.ts └── introspection │ └── Introspectable.behavior.ts ├── assets └── solidstate_mark.png ├── contracts ├── meta │ ├── _IContext.sol │ ├── IContext.sol │ ├── Context.sol │ ├── _IForwardedMetaTransactionContext.sol │ ├── IForwardedMetaTransactionContext.sol │ └── _Context.sol ├── interfaces │ ├── _IERC1271.sol │ ├── _IERC2612.sol │ ├── _IERC2771.sol │ ├── _IERC5267.sol │ ├── _IERC5313.sol │ ├── _IERC1967Beacon.sol │ ├── _IERC20Metadata.sol │ ├── _IERC721Metadata.sol │ ├── _IERC721Receiver.sol │ ├── _IERC3156FlashLender.sol │ ├── _IERC721Enumerable.sol │ ├── _IERC3156FlashBorrower.sol │ ├── _IERC165.sol │ ├── _IERC1155Metadata.sol │ ├── _IERC1155Receiver.sol │ ├── IERC1967Proxy.sol │ ├── _IERC2981.sol │ ├── _IWETH.sol │ ├── _IERC1404.sol │ ├── _IERC1967Proxy.sol │ ├── _IERC173.sol │ ├── IERC1155Metadata.sol │ ├── IERC721Receiver.sol │ ├── _IERC20.sol │ ├── _IERC2535DiamondLoupe.sol │ ├── IERC1967Beacon.sol │ ├── IERC5313.sol │ ├── IERC1271.sol │ ├── IERC165.sol │ ├── IERC2771.sol │ ├── _IERC2535DiamondCut.sol │ ├── IERC173.sol │ ├── _IERC721.sol │ ├── _IERC4626.sol │ ├── IERC721Metadata.sol │ ├── IERC20Metadata.sol │ ├── IWETH.sol │ ├── _IERC1155.sol │ ├── IERC2535DiamondCut.sol │ ├── IERC2981.sol │ ├── IERC3156FlashBorrower.sol │ ├── IERC5267.sol │ ├── IERC1404.sol │ ├── IERC721Enumerable.sol │ ├── IERC2612.sol │ ├── IERC1155Receiver.sol │ ├── IERC3156FlashLender.sol │ └── IERC2535DiamondLoupe.sol ├── utils │ ├── _IMulticall.sol │ ├── Int256.sol │ ├── Block.sol │ ├── Multicall.sol │ ├── IMulticall.sol │ ├── Bool.sol │ ├── _Multicall.sol │ └── Panic.sol ├── proxy │ ├── beacon │ │ ├── _IBeaconProxy.sol │ │ ├── diamond │ │ │ ├── _IDiamondBeaconProxy.sol │ │ │ ├── IDiamondBeaconProxy.sol │ │ │ ├── DiamondBeaconProxy.sol │ │ │ └── _DiamondBeaconProxy.sol │ │ ├── transparent │ │ │ ├── _ITransparentBeaconProxy.sol │ │ │ ├── _ITransparentBeaconProxyWithAdminFunctions.sol │ │ │ ├── ITransparentBeaconProxy.sol │ │ │ ├── ITransparentBeaconProxyWithAdminFunctions.sol │ │ │ ├── TransparentBeaconProxy.sol │ │ │ └── _TransparentBeaconProxy.sol │ │ ├── IBeaconProxy.sol │ │ ├── BeaconProxy.sol │ │ └── _BeaconProxy.sol │ ├── transparent │ │ ├── _ITransparentProxy.sol │ │ ├── _ITransparentProxyWithAdminFunctions.sol │ │ ├── ITransparentProxy.sol │ │ ├── TransparentProxy.sol │ │ ├── ITransparentProxyWithAdminFunctions.sol │ │ └── _TransparentProxy.sol │ ├── diamond │ │ ├── IDiamondProxy.sol │ │ ├── fallback │ │ │ ├── _IDiamondProxyFallback.sol │ │ │ ├── IDiamondProxyFallback.sol │ │ │ └── DiamondProxyFallback.sol │ │ ├── writable │ │ │ ├── _IDiamondProxyWritable.sol │ │ │ ├── IDiamondProxyWritable.sol │ │ │ ├── _DiamondProxyWritable.sol │ │ │ └── DiamondProxyWritable.sol │ │ ├── _ISolidstateDiamondProxy.sol │ │ ├── readable │ │ │ ├── IDiamondProxyReadable.sol │ │ │ ├── _IDiamondProxyReadable.sol │ │ │ └── DiamondProxyReadable.sol │ │ ├── ISolidstateDiamondProxy.sol │ │ ├── _IDiamondProxy.sol │ │ ├── DiamondProxy.sol │ │ └── _SolidstateDiamondProxy.sol │ ├── _IProxy.sol │ ├── IProxy.sol │ └── Proxy.sol ├── access │ ├── reentrancy_guard │ │ ├── _IReentrancyGuard.sol │ │ ├── IReentrancyGuard.sol │ │ ├── _ITransientReentrancyGuard.sol │ │ ├── ITransientReentrancyGuard.sol │ │ ├── ReentrancyGuard.sol │ │ └── TransientReentrancyGuard.sol │ ├── initializable │ │ ├── IInitializable.sol │ │ ├── _IInitializable.sol │ │ ├── Initializable.sol │ │ └── _Initializable.sol │ ├── ownable │ │ ├── IOwnable.sol │ │ ├── _IOwnable.sol │ │ ├── safe │ │ │ ├── _ISafeOwnable.sol │ │ │ ├── ISafeOwnable.sol │ │ │ └── SafeOwnable.sol │ │ └── Ownable.sol │ ├── pausable │ │ ├── _IPausable.sol │ │ ├── IPausable.sol │ │ ├── Pausable.sol │ │ └── _Pausable.sol │ ├── partially_pausable │ │ ├── _IPartiallyPausable.sol │ │ ├── IPartiallyPausable.sol │ │ └── PartiallyPausable.sol │ └── access_control │ │ ├── ownable │ │ ├── _IAccessControlOwnable.sol │ │ ├── IAccessControlOwnable.sol │ │ └── AccessControlOwnable.sol │ │ └── _IAccessControl.sol ├── signature │ └── contract_signer │ │ ├── _IContractSigner.sol │ │ ├── IContractSigner.sol │ │ ├── ownable │ │ ├── _IContractSignerOwnable.sol │ │ ├── IContractSignerOwnable.sol │ │ ├── ContractSignerOwnable.sol │ │ └── _ContractSignerOwnable.sol │ │ ├── ContractSigner.sol │ │ └── _ContractSigner.sol ├── token │ ├── multi │ │ ├── enumerable │ │ │ ├── _IMultiTokenEnumerable.sol │ │ │ └── IMultiTokenEnumerable.sol │ │ ├── metadata │ │ │ ├── _IMultiTokenMetadata.sol │ │ │ ├── IMultiTokenMetadata.sol │ │ │ └── MultiTokenMetadata.sol │ │ ├── _ISolidstateMultiToken.sol │ │ ├── IMultiToken.sol │ │ ├── ISolidstateMultiToken.sol │ │ ├── _IMultiToken.sol │ │ ├── _SolidstateMultiToken.sol │ │ └── SolidstateMultiToken.sol │ ├── fungible │ │ ├── metadata │ │ │ ├── _IFungibleTokenMetadata.sol │ │ │ ├── IFungibleTokenMetadata.sol │ │ │ └── FungibleTokenMetadata.sol │ │ ├── snapshot │ │ │ ├── _IFungibleTokenSnapshot.sol │ │ │ ├── IFungibleTokenSnapshot.sol │ │ │ └── FungibleTokenSnapshot.sol │ │ ├── permit │ │ │ ├── IFungibleTokenPermit.sol │ │ │ └── _IFungibleTokenPermit.sol │ │ ├── IFungibleToken.sol │ │ ├── extended │ │ │ ├── _IFungibleTokenExtended.sol │ │ │ ├── FungibleTokenExtended.sol │ │ │ └── IFungibleTokenExtended.sol │ │ ├── restricted │ │ │ ├── _IRestrictedFungibleToken.sol │ │ │ └── IRestrictedFungibleToken.sol │ │ ├── _ISolidstateFungibleToken.sol │ │ ├── vault │ │ │ ├── IFungibleVaultToken.sol │ │ │ └── _IFungibleVaultToken.sol │ │ ├── ISolidstateFungibleToken.sol │ │ ├── _SolidstateFungibleToken.sol │ │ ├── _IFungibleToken.sol │ │ └── SolidstateFungibleToken.sol │ ├── common │ │ └── royalty │ │ │ ├── _INFTRoyalty.sol │ │ │ ├── INFTRoyalty.sol │ │ │ └── NFTRoyalty.sol │ └── non_fungible │ │ ├── enumerable │ │ ├── _INonFungibleTokenEnumerable.sol │ │ ├── INonFungibleTokenEnumerable.sol │ │ └── NonFungibleTokenEnumerable.sol │ │ ├── metadata │ │ ├── INonFungibleTokenMetadata.sol │ │ ├── _INonFungibleTokenMetadata.sol │ │ └── NonFungibleTokenMetadata.sol │ │ ├── INonFungibleToken.sol │ │ ├── ISolidstateNonFungibleToken.sol │ │ ├── _ISolidstateNonFungibleToken.sol │ │ └── _INonFungibleToken.sol ├── introspection │ ├── _IIntrospectable.sol │ ├── IIntrospectable.sol │ ├── Introspectable.sol │ └── _Introspectable.sol ├── beacon │ ├── _IBeacon.sol │ ├── diamond │ │ ├── _IDiamondBeacon.sol │ │ └── IDiamondBeacon.sol │ ├── IBeacon.sol │ ├── Beacon.sol │ └── _Beacon.sol ├── test │ ├── AddressTest.sol │ ├── ReentrancyGuardTest.sol │ ├── TransientSlotTest.sol │ ├── BoolTest.sol │ ├── TransientReentrancyGuardTest.sol │ ├── Bytes32Test.sol │ ├── TimestampTest.sol │ └── DurationTest.sol ├── package.json ├── storage │ ├── BeaconStorage.sol │ ├── ERC1271Storage.sol │ ├── ERC2771Storage.sol │ ├── ERC165Storage.sol │ ├── PausableStorage.sol │ ├── InitializableStorage.sol │ ├── ReentrancyGuardStorage.sol │ ├── ERC2981Storage.sol │ ├── ERC173Storage.sol │ ├── AccessControlStorage.sol │ ├── ERC2535Storage.sol │ ├── ERC721Storage.sol │ ├── ERC1155Storage.sol │ └── ERC20Storage.sol └── cryptography │ └── MerkleProof.sol ├── lerna.json ├── pnpm-workspace.yaml ├── .gitignore ├── .prettierrc.json ├── tsconfig.json ├── exec-staged.config.ts ├── tasks └── compile.ts ├── abi ├── README.md └── package.json ├── patches ├── typechain.patch └── @typechain__hardhat.patch ├── slippy.config.js ├── test ├── utils │ ├── Block.ts │ ├── Panic.ts │ └── Int256.ts ├── token │ ├── non_fungible │ │ ├── enumerable │ │ │ └── NonFungibleTokenEnumerable.ts │ │ └── SolidstateNonFungibleToken.ts │ ├── fungible │ │ ├── extended │ │ │ └── FungibleTokenExtended.ts │ │ ├── metadata │ │ │ └── FungibleTokenMetadata.ts │ │ ├── SolidstateFungibleToken.ts │ │ └── permit │ │ │ └── FungibleTokenPermit.ts │ └── multi │ │ ├── enumerable │ │ └── MultiTokenEnumerable.ts │ │ └── SolidstateMultiToken.ts ├── beacon │ └── Beacon.ts ├── proxy │ └── diamond │ │ └── writable │ │ └── DiamondProxyWritable.ts ├── pragma.ts ├── storage │ └── ERC1967Storage.ts └── cryptography │ └── MerkleProof.ts ├── LICENSE.md └── hardhat.config.ts /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pnpm exec-staged 3 | -------------------------------------------------------------------------------- /lib/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import '@nomicfoundation/hardhat-ethers'; 2 | -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": "hardhat/register", 3 | "timeout": 20000 4 | } 5 | -------------------------------------------------------------------------------- /spec/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import '@nomicfoundation/hardhat-chai-matchers'; 2 | import '@nomicfoundation/hardhat-ethers'; 3 | -------------------------------------------------------------------------------- /assets/solidstate_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidstate-network/solidstate-solidity/HEAD/assets/solidstate_mark.png -------------------------------------------------------------------------------- /lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /spec/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /contracts/meta/_IContext.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IContext {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1271.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC1271 {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC2612.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC2612 {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC2771.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC2771 {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC5267.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC5267 {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC5313.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC5313 {} 6 | -------------------------------------------------------------------------------- /contracts/utils/_IMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IMulticall {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1967Beacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC1967Beacon {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC20Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC20Metadata {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC721Metadata {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC721Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC721Receiver {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC3156FlashLender.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC3156FlashLender {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC721Enumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC721Enumerable {} 6 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC3156FlashBorrower.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC3156FlashBorrower {} 6 | -------------------------------------------------------------------------------- /contracts/meta/IContext.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IContext } from './_IContext.sol'; 6 | 7 | interface IContext is _IContext {} 8 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | /** 6 | * @title ERC165 interface registration interface 7 | */ 8 | interface _IERC165 {} 9 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/_IBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IProxy } from '../_IProxy.sol'; 6 | 7 | interface _IBeaconProxy is _IProxy {} 8 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-next.2", 3 | "packages": ["abi", "contracts", "lib", "spec"], 4 | "command": { 5 | "publish": { 6 | "forcePublish": "*" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /contracts/access/reentrancy_guard/_IReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IReentrancyGuard { 6 | error ReentrancyGuard__ReentrantCall(); 7 | } 8 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1155Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC1155Metadata { 6 | event URI(string value, uint256 indexed tokenId); 7 | } 8 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | interface _IERC1155Receiver is _IERC165 {} 8 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/_ITransparentProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IProxy } from '../_IProxy.sol'; 6 | 7 | interface _ITransparentProxy is _IProxy {} 8 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC1967Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1967Proxy } from './_IERC1967Proxy.sol'; 6 | 7 | interface IERC1967Proxy is _IERC1967Proxy {} 8 | -------------------------------------------------------------------------------- /contracts/access/initializable/IInitializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IInitializable } from './_IInitializable.sol'; 6 | 7 | interface IInitializable is _IInitializable {} 8 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bigint_conversion'; 2 | export * from './erc20_permit'; 3 | export * from './mocha_describe_filter'; 4 | export * from './mock_contract'; 5 | export * from './sign_data'; 6 | export * from './storage_layout'; 7 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - ./abi/ 3 | - ./contracts/ 4 | - ./lib/ 5 | - ./spec/ 6 | 7 | patchedDependencies: 8 | typechain: patches/typechain.patch 9 | '@typechain/hardhat': patches/@typechain__hardhat.patch 10 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/diamond/_IDiamondBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IBeaconProxy } from '../_IBeaconProxy.sol'; 6 | 7 | interface _IDiamondBeaconProxy is _IBeaconProxy {} 8 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/_IContractSigner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1271 } from '../../interfaces/_IERC1271.sol'; 6 | 7 | interface _IContractSigner is _IERC1271 {} 8 | -------------------------------------------------------------------------------- /contracts/token/multi/enumerable/_IMultiTokenEnumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IMultiToken } from '../_IMultiToken.sol'; 6 | 7 | interface _IMultiTokenEnumerable is _IMultiToken {} 8 | -------------------------------------------------------------------------------- /contracts/access/reentrancy_guard/IReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IReentrancyGuard } from './_IReentrancyGuard.sol'; 6 | 7 | interface IReentrancyGuard is _IReentrancyGuard {} 8 | -------------------------------------------------------------------------------- /contracts/meta/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Context } from './_Context.sol'; 6 | import { IContext } from './IContext.sol'; 7 | 8 | abstract contract Context is IContext, _Context {} 9 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC2981.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | /** 8 | * @title ERC2981 interface 9 | */ 10 | interface _IERC2981 is _IERC165 {} 11 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/transparent/_ITransparentBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IBeaconProxy } from '../_IBeaconProxy.sol'; 6 | 7 | interface _ITransparentBeaconProxy is _IBeaconProxy {} 8 | -------------------------------------------------------------------------------- /contracts/access/initializable/_IInitializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IInitializable { 6 | error Initializable__AlreadyInitialized(); 7 | 8 | event Initialized(uint8 version); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/interfaces/_IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC20 } from './_IERC20.sol'; 6 | import { _IERC20Metadata } from './_IERC20Metadata.sol'; 7 | 8 | interface _IWETH is _IERC20, _IERC20Metadata {} 9 | -------------------------------------------------------------------------------- /contracts/access/reentrancy_guard/_ITransientReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IReentrancyGuard } from './_IReentrancyGuard.sol'; 6 | 7 | interface _ITransientReentrancyGuard is _IReentrancyGuard {} 8 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/IBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IProxy } from '../IProxy.sol'; 6 | import { _IBeaconProxy } from './_IBeaconProxy.sol'; 7 | 8 | interface IBeaconProxy is _IBeaconProxy, IProxy {} 9 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/IDiamondProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IProxy } from '../IProxy.sol'; 6 | import { _IDiamondProxy } from './_IDiamondProxy.sol'; 7 | 8 | interface IDiamondProxy is _IDiamondProxy, IProxy {} 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | lerna-debug.log 4 | 5 | typechain-types/ 6 | dist/ 7 | 8 | artifacts/ 9 | cache/ 10 | 11 | abi/*.json 12 | !abi/package.json 13 | 14 | gasreport.txt 15 | 16 | coverage/ 17 | coverage.json 18 | 19 | contracts-exposed/ 20 | 21 | .env 22 | -------------------------------------------------------------------------------- /lib/mocha_describe_filter.ts: -------------------------------------------------------------------------------- 1 | import { Suite } from 'mocha'; 2 | 3 | export function describeFilter(skips?: string[]) { 4 | let set = new Set(skips); 5 | return (title: string, suite: (this: Suite) => void) => { 6 | set.has(title) || describe(title, suite); 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/_ITransparentProxyWithAdminFunctions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ITransparentProxy } from './_ITransparentProxy.sol'; 6 | 7 | interface _ITransparentProxyWithAdminFunctions is _ITransparentProxy {} 8 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "trailingComma": "all", 5 | "bracketSpacing": true, 6 | "plugins": [ 7 | "prettier-plugin-packagejson", 8 | "prettier-plugin-solidity", 9 | "@trivago/prettier-plugin-sort-imports" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /contracts/introspection/_IIntrospectable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from '../interfaces/_IERC165.sol'; 6 | 7 | interface _IIntrospectable is _IERC165 { 8 | error Introspectable__InvalidInterfaceId(); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/beacon/_IBeacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IOwnable } from '../access/ownable/_IOwnable.sol'; 6 | import { _IERC1967Beacon } from '../interfaces/_IERC1967Beacon.sol'; 7 | 8 | interface _IBeacon is _IERC1967Beacon, _IOwnable {} 9 | -------------------------------------------------------------------------------- /contracts/introspection/IIntrospectable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC165 } from '../interfaces/IERC165.sol'; 6 | import { _IIntrospectable } from './_IIntrospectable.sol'; 7 | 8 | interface IIntrospectable is _IIntrospectable, IERC165 {} 9 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/ITransparentProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IProxy } from '../IProxy.sol'; 6 | import { _ITransparentProxy } from './_ITransparentProxy.sol'; 7 | 8 | interface ITransparentProxy is _ITransparentProxy, IProxy {} 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "lib": ["es2021"], 5 | "module": "commonjs", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "outDir": "dist", 9 | "declaration": true, 10 | "resolveJsonModule": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1404.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC20 } from './_IERC20.sol'; 6 | 7 | /** 8 | * @title ERC1404 interface 9 | * @dev see https://eips.ethereum.org/EIPS/eip-1404 10 | */ 11 | interface _IERC1404 is _IERC20 {} 12 | -------------------------------------------------------------------------------- /contracts/meta/_IForwardedMetaTransactionContext.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2771 } from '../interfaces/_IERC2771.sol'; 6 | import { _IContext } from './_IContext.sol'; 7 | 8 | interface _IForwardedMetaTransactionContext is _IContext, _IERC2771 {} 9 | -------------------------------------------------------------------------------- /contracts/access/initializable/Initializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Initializable } from './_Initializable.sol'; 6 | import { IInitializable } from './IInitializable.sol'; 7 | 8 | abstract contract Initializable is IInitializable, _Initializable {} 9 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/IContractSigner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1271 } from '../../interfaces/IERC1271.sol'; 6 | import { _IContractSigner } from './_IContractSigner.sol'; 7 | 8 | interface IContractSigner is _IContractSigner, IERC1271 {} 9 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/diamond/IDiamondBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IBeaconProxy } from '../IBeaconProxy.sol'; 6 | import { _IDiamondBeaconProxy } from './_IDiamondBeaconProxy.sol'; 7 | 8 | interface IDiamondBeaconProxy is _IDiamondBeaconProxy, IBeaconProxy {} 9 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1967Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | interface _IERC1967Proxy { 6 | event Upgraded(address indexed implementation); 7 | event BeaconUpgraded(address indexed beacon); 8 | event AdminChanged(address previousAdmin, address newAdmin); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/fallback/_IDiamondProxyFallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IOwnable } from '../../../access/ownable/_IOwnable.sol'; 6 | import { _IDiamondProxy } from '../_IDiamondProxy.sol'; 7 | 8 | interface _IDiamondProxyFallback is _IDiamondProxy, _IOwnable {} 9 | -------------------------------------------------------------------------------- /contracts/access/ownable/IOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC173 } from '../../interfaces/IERC173.sol'; 6 | import { IContext } from '../../meta/IContext.sol'; 7 | import { _IOwnable } from './_IOwnable.sol'; 8 | 9 | interface IOwnable is _IOwnable, IContext, IERC173 {} 10 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/transparent/_ITransparentBeaconProxyWithAdminFunctions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ITransparentBeaconProxy } from './_ITransparentBeaconProxy.sol'; 6 | 7 | interface _ITransparentBeaconProxyWithAdminFunctions is 8 | _ITransparentBeaconProxy 9 | {} 10 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/ownable/_IContractSignerOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IOwnable } from '../../../access/ownable/_IOwnable.sol'; 6 | import { _IContractSigner } from '../_IContractSigner.sol'; 7 | 8 | interface _IContractSignerOwnable is _IContractSigner, _IOwnable {} 9 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/transparent/ITransparentBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IBeaconProxy } from '../IBeaconProxy.sol'; 6 | import { _ITransparentBeaconProxy } from './_ITransparentBeaconProxy.sol'; 7 | 8 | interface ITransparentBeaconProxy is _ITransparentBeaconProxy, IBeaconProxy {} 9 | -------------------------------------------------------------------------------- /contracts/token/fungible/metadata/_IFungibleTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC20Metadata } from '../../../interfaces/_IERC20Metadata.sol'; 6 | 7 | /** 8 | * @title FungibleToken metadata internal interface 9 | */ 10 | interface _IFungibleTokenMetadata is _IERC20Metadata {} 11 | -------------------------------------------------------------------------------- /contracts/beacon/diamond/_IDiamondBeacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IOwnable } from '../../access/ownable/_IOwnable.sol'; 6 | import { _IDiamondProxyWritable } from '../../proxy/diamond/writable/_IDiamondProxyWritable.sol'; 7 | 8 | interface _IDiamondBeacon is _IOwnable, _IDiamondProxyWritable {} 9 | -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | # Solidstate Library 2 | 3 | Utility functions for interaction with Solidstate contracts. Part of the Solidstate Solidity monorepo. 4 | 5 | ## Installation 6 | 7 | Install the package as a development dependency: 8 | 9 | ```bash 10 | npm install --save-dev @solidstate/library 11 | # or 12 | pnpm add -D @solidstate/library 13 | ``` 14 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/ownable/IContractSignerOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IContractSigner } from '../IContractSigner.sol'; 6 | import { _IContractSignerOwnable } from './_IContractSignerOwnable.sol'; 7 | 8 | interface IContractSignerOwnable is _IContractSignerOwnable, IContractSigner {} 9 | -------------------------------------------------------------------------------- /contracts/access/ownable/_IOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC173 } from '../../interfaces/_IERC173.sol'; 6 | import { _IContext } from '../../meta/_IContext.sol'; 7 | 8 | interface _IOwnable is _IERC173, _IContext { 9 | error Ownable__NotOwner(); 10 | error Ownable__NotTransitiveOwner(); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/token/multi/metadata/_IMultiTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1155Metadata } from '../../../interfaces/_IERC1155Metadata.sol'; 6 | 7 | /** 8 | * @title Partial MultiTokenMetadata interface needed by internal functions 9 | */ 10 | interface _IMultiTokenMetadata is _IERC1155Metadata {} 11 | -------------------------------------------------------------------------------- /contracts/access/pausable/_IPausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IContext } from '../../meta/_IContext.sol'; 6 | 7 | interface _IPausable is _IContext { 8 | error Pausable__Paused(); 9 | error Pausable__NotPaused(); 10 | 11 | event Paused(address account); 12 | event Unpaused(address account); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/proxy/_IProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1967Proxy } from '../interfaces/_IERC1967Proxy.sol'; 6 | import { _IContext } from '../meta/_IContext.sol'; 7 | 8 | interface _IProxy is _IERC1967Proxy, _IContext { 9 | error Proxy__ImplementationIsNotContract(); 10 | error Proxy__SenderIsNotAdmin(); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/token/common/royalty/_INFTRoyalty.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2981 } from '../../../interfaces/_IERC2981.sol'; 6 | import { _IIntrospectable } from '../../../introspection/_IIntrospectable.sol'; 7 | 8 | interface _INFTRoyalty is _IERC2981, _IIntrospectable { 9 | error NFTRoyalty__RoyaltyTooHigh(); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/token/fungible/snapshot/_IFungibleTokenSnapshot.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IFungibleToken } from '../_IFungibleToken.sol'; 6 | 7 | interface _IFungibleTokenSnapshot is _IFungibleToken { 8 | error FungibleTokenSnapshot__SnapshotIdDoesNotExists(); 9 | error FungibleTokenSnapshot__SnapshotIdIsZero(); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/access/reentrancy_guard/ITransientReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ITransientReentrancyGuard } from './_ITransientReentrancyGuard.sol'; 6 | import { IReentrancyGuard } from './IReentrancyGuard.sol'; 7 | 8 | interface ITransientReentrancyGuard is 9 | _ITransientReentrancyGuard, 10 | IReentrancyGuard 11 | {} 12 | -------------------------------------------------------------------------------- /contracts/token/common/royalty/INFTRoyalty.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2981 } from '../../../interfaces/IERC2981.sol'; 6 | import { IIntrospectable } from '../../../introspection/IIntrospectable.sol'; 7 | import { _INFTRoyalty } from './_INFTRoyalty.sol'; 8 | 9 | interface INFTRoyalty is _INFTRoyalty, IERC2981, IIntrospectable {} 10 | -------------------------------------------------------------------------------- /exec-staged.config.ts: -------------------------------------------------------------------------------- 1 | import type { ExecStagedUserConfig } from 'exec-staged/types'; 2 | 3 | const config: ExecStagedUserConfig = [ 4 | // 'knip', 5 | // 'knip --strict', 6 | { 7 | task: 'slippy $FILES', 8 | glob: 'contracts/**/*.sol', 9 | }, 10 | { 11 | task: 'prettier --write $FILES', 12 | glob: '*.{js,ts,sol,json,md}', 13 | }, 14 | ]; 15 | 16 | export default config; 17 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/enumerable/_INonFungibleTokenEnumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC721Enumerable } from '../../../interfaces/_IERC721Enumerable.sol'; 6 | import { _INonFungibleToken } from '../_INonFungibleToken.sol'; 7 | 8 | interface _INonFungibleTokenEnumerable is 9 | _INonFungibleToken, 10 | _IERC721Enumerable 11 | {} 12 | -------------------------------------------------------------------------------- /contracts/access/reentrancy_guard/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ReentrancyGuard } from './_ReentrancyGuard.sol'; 6 | import { IReentrancyGuard } from './IReentrancyGuard.sol'; 7 | 8 | /** 9 | * @title Utility contract for preventing reentrancy attacks 10 | */ 11 | abstract contract ReentrancyGuard is IReentrancyGuard, _ReentrancyGuard {} 12 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC173.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC5313 } from './_IERC5313.sol'; 6 | 7 | /** 8 | * @title Partial ERC173 interface needed by internal functions 9 | */ 10 | interface _IERC173 is _IERC5313 { 11 | event OwnershipTransferred( 12 | address indexed previousOwner, 13 | address indexed newOwner 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /contracts/token/fungible/permit/IFungibleTokenPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2612 } from '../../../interfaces/IERC2612.sol'; 6 | import { IERC5267 } from '../../../interfaces/IERC5267.sol'; 7 | import { _IFungibleTokenPermit } from './_IFungibleTokenPermit.sol'; 8 | 9 | interface IFungibleTokenPermit is _IFungibleTokenPermit, IERC2612, IERC5267 {} 10 | -------------------------------------------------------------------------------- /contracts/token/multi/metadata/IMultiTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1155Metadata } from '../../../interfaces/IERC1155Metadata.sol'; 6 | import { _IMultiTokenMetadata } from './_IMultiTokenMetadata.sol'; 7 | 8 | /** 9 | * @title MultiTokenMetadata interface 10 | */ 11 | interface IMultiTokenMetadata is _IMultiTokenMetadata, IERC1155Metadata {} 12 | -------------------------------------------------------------------------------- /lib/bigint_conversion.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat'; 2 | 3 | export function bigintToAddress(bn: any) { 4 | return ethers.getAddress(ethers.zeroPadValue(ethers.toBeHex(bn), 20)); 5 | } 6 | 7 | export function bigintToBytes16(bn: any) { 8 | return ethers.zeroPadValue(ethers.toBeHex(bn), 16); 9 | } 10 | export function bigintToBytes32(bn: any) { 11 | return ethers.zeroPadValue(ethers.toBeHex(bn), 32); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC1155Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1155Metadata } from './_IERC1155Metadata.sol'; 6 | 7 | interface IERC1155Metadata is _IERC1155Metadata { 8 | /** 9 | * @notice get generated URI for given token 10 | * @return token URI 11 | */ 12 | function uri(uint256 tokenId) external view returns (string memory); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/token/fungible/IFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC20 } from '../../interfaces/IERC20.sol'; 6 | import { IContext } from '../../meta/IContext.sol'; 7 | import { _IFungibleToken } from './_IFungibleToken.sol'; 8 | 9 | /** 10 | * @title FungibleToken base interface 11 | */ 12 | interface IFungibleToken is _IFungibleToken, IERC20, IContext {} 13 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC721Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC721Receiver } from './_IERC721Receiver.sol'; 6 | 7 | interface IERC721Receiver is _IERC721Receiver { 8 | function onERC721Received( 9 | address operator, 10 | address from, 11 | uint256 tokenId, 12 | bytes calldata data 13 | ) external returns (bytes4); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/token/fungible/metadata/IFungibleTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC20Metadata } from '../../../interfaces/IERC20Metadata.sol'; 6 | import { _IFungibleTokenMetadata } from './_IFungibleTokenMetadata.sol'; 7 | 8 | /** 9 | * @title FungibleToken metadata interface 10 | */ 11 | interface IFungibleTokenMetadata is _IFungibleTokenMetadata, IERC20Metadata {} 12 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | /** 6 | * @title Partial ERC20 interface needed by internal functions 7 | */ 8 | interface _IERC20 { 9 | event Transfer(address indexed from, address indexed to, uint256 value); 10 | 11 | event Approval( 12 | address indexed owner, 13 | address indexed spender, 14 | uint256 value 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /tasks/compile.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import { TASK_COMPILE } from 'hardhat/builtin-tasks/task-names'; 3 | import { task } from 'hardhat/config'; 4 | import path from 'path'; 5 | 6 | task(TASK_COMPILE).setAction(async (args, hre, runSuper) => { 7 | await fs.promises.rm(path.resolve(hre.config.paths.sources, 'index.sol'), { 8 | force: true, 9 | }); 10 | await runSuper(args); 11 | await hre.run('organize-test-files'); 12 | }); 13 | -------------------------------------------------------------------------------- /abi/README.md: -------------------------------------------------------------------------------- 1 | # Solidstate ABI 2 | 3 | Solidstate smart contract ABIs. Part of the Solidstate Solidity monorepo. 4 | 5 | ## Installation 6 | 7 | Install the package as a development dependency: 8 | 9 | ```bash 10 | npm install --save-dev @solidstate/abi 11 | # or 12 | pnpm add -D @solidstate/abi 13 | ``` 14 | 15 | ## Development 16 | 17 | The contents of this package are generated automatically as a part of the contract compilation process. 18 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC2535DiamondLoupe.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | /** 8 | * @title ERC2535 read interface for internal functions 9 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 10 | */ 11 | interface _IERC2535DiamondLoupe is _IERC165 { 12 | struct Facet { 13 | address target; 14 | bytes4[] selectors; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/token/fungible/extended/_IFungibleTokenExtended.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IFungibleToken } from '../_IFungibleToken.sol'; 6 | 7 | /** 8 | * @title FungibleToken extended internal interface 9 | */ 10 | interface _IFungibleTokenExtended is _IFungibleToken { 11 | error FungibleTokenExtended__ExcessiveAllowance(); 12 | error FungibleTokenExtended__InsufficientAllowance(); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/meta/IForwardedMetaTransactionContext.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2771 } from '../interfaces/IERC2771.sol'; 6 | import { _IForwardedMetaTransactionContext } from './_IForwardedMetaTransactionContext.sol'; 7 | import { IContext } from './IContext.sol'; 8 | 9 | interface IForwardedMetaTransactionContext is 10 | _IForwardedMetaTransactionContext, 11 | IContext, 12 | IERC2771 13 | {} 14 | -------------------------------------------------------------------------------- /contracts/token/fungible/restricted/_IRestrictedFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1404 } from '../../../interfaces/_IERC1404.sol'; 6 | import { _IFungibleToken } from '../_IFungibleToken.sol'; 7 | 8 | /** 9 | * @title ERC1404 base interface 10 | */ 11 | interface _IRestrictedFungibleToken is _IERC1404, _IFungibleToken { 12 | error RestrictedFungibleToken__ArrayLengthMismatch(); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/utils/Int256.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | library Int256 { 6 | /** 7 | * @notice convert int256 to bytes32 8 | * @param value int256 to convert to bytes32 9 | * @return result bytes32 representation of int256 10 | */ 11 | function toBytes32(int256 value) internal pure returns (bytes32 result) { 12 | assembly { 13 | result := value 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/access/pausable/IPausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IContext } from '../../meta/IContext.sol'; 6 | import { _IPausable } from './_IPausable.sol'; 7 | 8 | interface IPausable is _IPausable, IContext { 9 | /** 10 | * @notice query whether contract is paused 11 | * @return status whether contract is paused 12 | */ 13 | function paused() external view returns (bool status); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/token/multi/_ISolidstateMultiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IMultiTokenEnumerable } from './enumerable/_IMultiTokenEnumerable.sol'; 6 | import { _IMultiTokenMetadata } from './metadata/_IMultiTokenMetadata.sol'; 7 | import { _IMultiToken } from './_IMultiToken.sol'; 8 | 9 | interface _ISolidstateMultiToken is 10 | _IMultiToken, 11 | _IMultiTokenEnumerable, 12 | _IMultiTokenMetadata 13 | {} 14 | -------------------------------------------------------------------------------- /contracts/access/partially_pausable/_IPartiallyPausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IContext } from '../../meta/_IContext.sol'; 6 | 7 | interface _IPartiallyPausable is _IContext { 8 | error PartiallyPausable__PartiallyPaused(); 9 | error PartiallyPausable__NotPartiallyPaused(); 10 | 11 | event PartiallyPaused(address account, bytes32 key); 12 | event PartiallyUnpaused(address account, bytes32 key); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/metadata/INonFungibleTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC721Metadata } from '../../../interfaces/IERC721Metadata.sol'; 6 | import { _INonFungibleTokenMetadata } from './_INonFungibleTokenMetadata.sol'; 7 | 8 | /** 9 | * @title NonFungibleTokenMetadata interface 10 | */ 11 | interface INonFungibleTokenMetadata is 12 | _INonFungibleTokenMetadata, 13 | IERC721Metadata 14 | {} 15 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/writable/_IDiamondProxyWritable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2535DiamondCut } from '../../../interfaces/_IERC2535DiamondCut.sol'; 6 | import { _IIntrospectable } from '../../../introspection/_IIntrospectable.sol'; 7 | import { _IDiamondProxy } from '../_IDiamondProxy.sol'; 8 | 9 | interface _IDiamondProxyWritable is 10 | _IERC2535DiamondCut, 11 | _IDiamondProxy, 12 | _IIntrospectable 13 | {} 14 | -------------------------------------------------------------------------------- /contracts/token/multi/IMultiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1155 } from '../../interfaces/IERC1155.sol'; 6 | import { IIntrospectable } from '../../introspection/IIntrospectable.sol'; 7 | import { IContext } from '../../meta/IContext.sol'; 8 | import { _IMultiToken } from './_IMultiToken.sol'; 9 | 10 | /** 11 | * @title MultiToken base interface 12 | */ 13 | interface IMultiToken is _IMultiToken, IERC1155, IIntrospectable, IContext {} 14 | -------------------------------------------------------------------------------- /contracts/access/access_control/ownable/_IAccessControlOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IOwnable } from '../../ownable/_IOwnable.sol'; 6 | import { _IAccessControl } from '../_IAccessControl.sol'; 7 | 8 | /** 9 | * @title Partial IAccessControlOwnable interface needed by internal functions 10 | */ 11 | interface _IAccessControlOwnable is _IAccessControl, _IOwnable { 12 | error AccessControlOwnable__InvalidActionOnDefaultAdminRole(); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/proxy/IProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1967Proxy } from '../interfaces/IERC1967Proxy.sol'; 6 | import { IContext } from '../meta/IContext.sol'; 7 | import { _IProxy } from './_IProxy.sol'; 8 | 9 | interface IProxy is _IProxy, IContext, IERC1967Proxy { 10 | /** 11 | * @notice delegate calls to EIP-1967 implementation contract 12 | */ 13 | fallback() external payable; 14 | 15 | receive() external payable; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/test/AddressTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { Address } from '../utils/Address.sol'; 6 | 7 | contract AddressTest { 8 | function sanitizeBytes32Test( 9 | address input 10 | ) external pure returns (bytes32 output) { 11 | // contaminate the higher-order bits 12 | assembly { 13 | input := or(input, shl(160, not(1))) 14 | } 15 | 16 | output = Address.toBytes32(input); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/access/access_control/ownable/IAccessControlOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IOwnable } from '../../ownable/IOwnable.sol'; 6 | import { IAccessControl } from '../IAccessControl.sol'; 7 | import { _IAccessControlOwnable } from './_IAccessControlOwnable.sol'; 8 | 9 | /** 10 | * @title AccessControlOwnable interface 11 | */ 12 | interface IAccessControlOwnable is 13 | _IAccessControlOwnable, 14 | IAccessControl, 15 | IOwnable 16 | {} 17 | -------------------------------------------------------------------------------- /contracts/access/ownable/safe/_ISafeOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { timestamp } from '../../../utils/time/Timestamp.sol'; 6 | import { _IOwnable } from '../_IOwnable.sol'; 7 | 8 | interface _ISafeOwnable is _IOwnable { 9 | event OwnershipTransferInitiated( 10 | address indexed previousOwner, 11 | address indexed newOwner, 12 | timestamp timelockEndTimestamp 13 | ); 14 | 15 | error SafeOwnable__NotNomineeOwner(); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC1967Beacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1967Beacon } from './_IERC1967Beacon.sol'; 6 | 7 | interface IERC1967Beacon is _IERC1967Beacon { 8 | /** 9 | * @notice query the address of the implementation that should be used by IERC1967Proxy instances 10 | * @return implementation address of the implementation contract 11 | */ 12 | function implementation() external view returns (address implementation); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/metadata/_INonFungibleTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC721Metadata } from '../../../interfaces/_IERC721Metadata.sol'; 6 | import { _INonFungibleToken } from '../_INonFungibleToken.sol'; 7 | 8 | /** 9 | * @title NonFungibleTokenMetadata internal interface 10 | */ 11 | interface _INonFungibleTokenMetadata is _INonFungibleToken, _IERC721Metadata { 12 | error NonFungibleTokenMetadata__NonExistentToken(); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC5313.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC5313 } from './_IERC5313.sol'; 6 | 7 | /** 8 | * @title Minimal contract ownership standard interface 9 | * @dev see https://eips.ethereum.org/EIPS/eip-5313 10 | */ 11 | interface IERC5313 is _IERC5313 { 12 | /** 13 | * @notice query the ERC173/ERC5313 contract owner 14 | * @return owner contract owner 15 | */ 16 | function owner() external view returns (address owner); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/enumerable/INonFungibleTokenEnumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC721Enumerable } from '../../../interfaces/IERC721Enumerable.sol'; 6 | import { INonFungibleToken } from '../INonFungibleToken.sol'; 7 | import { _INonFungibleTokenEnumerable } from './_NonFungibleTokenEnumerable.sol'; 8 | 9 | interface INonFungibleTokenEnumerable is 10 | _INonFungibleTokenEnumerable, 11 | INonFungibleToken, 12 | IERC721Enumerable 13 | {} 14 | -------------------------------------------------------------------------------- /contracts/token/fungible/restricted/IRestrictedFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1404 } from '../../../interfaces/IERC1404.sol'; 6 | import { IFungibleToken } from '../IFungibleToken.sol'; 7 | import { _IRestrictedFungibleToken } from './_IRestrictedFungibleToken.sol'; 8 | 9 | /** 10 | * @title ERC1404 base interface 11 | */ 12 | interface IRestrictedFungibleToken is 13 | _IRestrictedFungibleToken, 14 | IFungibleToken, 15 | IERC1404 16 | {} 17 | -------------------------------------------------------------------------------- /contracts/access/partially_pausable/IPartiallyPausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IPartiallyPausable } from './_IPartiallyPausable.sol'; 6 | 7 | interface IPartiallyPausable is _IPartiallyPausable { 8 | /** 9 | * @notice query whether contract is paused in the scope of given key 10 | * @return status whether contract is paused in the scope of given key 11 | */ 12 | function partiallyPaused(bytes32 key) external view returns (bool status); 13 | } 14 | -------------------------------------------------------------------------------- /lib/storage_layout.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat'; 2 | 3 | // TODO: rename to indicate that formula is from EIP-7201 4 | export function seedToStorageSlot(seed: string): string { 5 | return ( 6 | '0x' + 7 | ( 8 | (BigInt( 9 | ethers.solidityPackedKeccak256( 10 | ['uint256'], 11 | [BigInt(ethers.solidityPackedKeccak256(['string'], [seed])) - 1n], 12 | ), 13 | ) / 14 | 256n) * 15 | 256n 16 | ) 17 | .toString(16) 18 | .padStart(64, '0') 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/utils/Block.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { timestamp as _timestamp } from './time/Timestamp.sol'; 6 | 7 | library Block { 8 | /** 9 | * @notice replacement for block.timestamp which returns the current time as a Timestamp type 10 | * @return blockTimestamp current timestamp 11 | */ 12 | function timestamp() internal view returns (_timestamp blockTimestamp) { 13 | assembly { 14 | blockTimestamp := timestamp() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/access/pausable/Pausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { Context } from '../../meta/Context.sol'; 6 | import { _Pausable } from './_Pausable.sol'; 7 | import { IPausable } from './IPausable.sol'; 8 | 9 | /** 10 | * @title Pausable security control module. 11 | */ 12 | abstract contract Pausable is IPausable, _Pausable, Context { 13 | /** 14 | * @inheritdoc IPausable 15 | */ 16 | function paused() external view returns (bool status) { 17 | status = _paused(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/token/multi/ISolidstateMultiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IMultiTokenEnumerable } from './enumerable/IMultiTokenEnumerable.sol'; 6 | import { IMultiTokenMetadata } from './metadata/IMultiTokenMetadata.sol'; 7 | import { _ISolidstateMultiToken } from './_ISolidstateMultiToken.sol'; 8 | import { IMultiToken } from './IMultiToken.sol'; 9 | 10 | interface ISolidstateMultiToken is 11 | _ISolidstateMultiToken, 12 | IMultiToken, 13 | IMultiTokenEnumerable, 14 | IMultiTokenMetadata 15 | {} 16 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/INonFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC721 } from '../../interfaces/IERC721.sol'; 6 | import { IIntrospectable } from '../../introspection/IIntrospectable.sol'; 7 | import { IContext } from '../../meta/IContext.sol'; 8 | import { _INonFungibleToken } from './_INonFungibleToken.sol'; 9 | 10 | /** 11 | * @title NonFungibleToken base interface 12 | */ 13 | interface INonFungibleToken is 14 | _INonFungibleToken, 15 | IERC721, 16 | IIntrospectable, 17 | IContext 18 | {} 19 | -------------------------------------------------------------------------------- /contracts/access/ownable/safe/ISafeOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IOwnable } from '../IOwnable.sol'; 6 | import { _ISafeOwnable } from './_ISafeOwnable.sol'; 7 | 8 | interface ISafeOwnable is _ISafeOwnable, IOwnable { 9 | /** 10 | * @notice get the nominated owner who has permission to call acceptOwnership 11 | */ 12 | function nomineeOwner() external view returns (address); 13 | 14 | /** 15 | * @notice accept transfer of contract ownership 16 | */ 17 | function acceptOwnership() external; 18 | } 19 | -------------------------------------------------------------------------------- /contracts/test/ReentrancyGuardTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { ReentrancyGuard } from '../access/reentrancy_guard/ReentrancyGuard.sol'; 6 | 7 | abstract contract ReentrancyGuardTest is ReentrancyGuard { 8 | function modifier_nonReentrant() external nonReentrant { 9 | // do nothing 10 | } 11 | 12 | function reentrancyTest() external nonReentrant { 13 | this.reentrancyTest(); 14 | } 15 | 16 | function crossFunctionReentrancyTest() external nonReentrant { 17 | this.reentrancyTest(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC1271.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1271 } from './_IERC1271.sol'; 6 | 7 | interface IERC1271 is _IERC1271 { 8 | /** 9 | * @notice return ERC1271 magic value if given signature is valid for contract 10 | * @param hash hashed data 11 | * @param signature signed hash 12 | * @return magicValue ERC1271 magic value or null bytes 13 | */ 14 | function isValidSignature( 15 | bytes32 hash, 16 | bytes memory signature 17 | ) external view returns (bytes4 magicValue); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/_ISolidstateDiamondProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IDiamondProxyFallback } from './fallback/_IDiamondProxyFallback.sol'; 6 | import { _IDiamondProxyReadable } from './readable/_IDiamondProxyReadable.sol'; 7 | import { _IDiamondProxyWritable } from './writable/_IDiamondProxyWritable.sol'; 8 | import { _IDiamondProxy } from './_IDiamondProxy.sol'; 9 | 10 | interface _ISolidstateDiamondProxy is 11 | _IDiamondProxy, 12 | _IDiamondProxyFallback, 13 | _IDiamondProxyReadable, 14 | _IDiamondProxyWritable 15 | {} 16 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | /** 8 | * @title ERC165 interface registration interface 9 | * @dev see https://eips.ethereum.org/EIPS/eip-165 10 | */ 11 | interface IERC165 is _IERC165 { 12 | /** 13 | * @notice query whether contract has registered support for given interface 14 | * @param interfaceId interface id 15 | * @return bool whether interface is supported 16 | */ 17 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/token/fungible/_ISolidstateFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IFungibleTokenExtended } from './extended/_IFungibleTokenExtended.sol'; 6 | import { _IFungibleTokenMetadata } from './metadata/_IFungibleTokenMetadata.sol'; 7 | import { _IFungibleTokenPermit } from './permit/_IFungibleTokenPermit.sol'; 8 | import { _IFungibleToken } from './_IFungibleToken.sol'; 9 | 10 | interface _ISolidstateFungibleToken is 11 | _IFungibleToken, 12 | _IFungibleTokenExtended, 13 | _IFungibleTokenMetadata, 14 | _IFungibleTokenPermit 15 | {} 16 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/writable/IDiamondProxyWritable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2535DiamondCut } from '../../../interfaces/IERC2535DiamondCut.sol'; 6 | import { IIntrospectable } from '../../../introspection/IIntrospectable.sol'; 7 | import { _IDiamondProxyWritable } from './_IDiamondProxyWritable.sol'; 8 | 9 | /** 10 | * @title Diamond proxy upgrade interface 11 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 12 | */ 13 | interface IDiamondProxyWritable is 14 | _IDiamondProxyWritable, 15 | IERC2535DiamondCut, 16 | IIntrospectable 17 | {} 18 | -------------------------------------------------------------------------------- /contracts/utils/Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Multicall } from './_Multicall.sol'; 6 | import { IMulticall } from './IMulticall.sol'; 7 | 8 | /** 9 | * @title Utility contract for supporting processing of multiple function calls in a single transaction 10 | */ 11 | abstract contract Multicall is IMulticall, _Multicall { 12 | /** 13 | * @inheritdoc IMulticall 14 | */ 15 | function multicall( 16 | bytes[] calldata data 17 | ) external returns (bytes[] memory results) { 18 | results = _multicall(data); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/proxy/Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { Context } from '../meta/Context.sol'; 6 | import { _Proxy } from './_Proxy.sol'; 7 | import { IProxy } from './IProxy.sol'; 8 | 9 | /** 10 | * @title Base proxy contract 11 | */ 12 | abstract contract Proxy is IProxy, _Proxy, Context { 13 | /** 14 | * @inheritdoc IProxy 15 | * @dev reverts if implementation address contains no code 16 | */ 17 | fallback() external payable { 18 | _fallback(); 19 | } 20 | 21 | receive() external payable { 22 | _receive(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/utils/IMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IMulticall } from './_IMulticall.sol'; 6 | 7 | /** 8 | * @title Interface for the Multicall utility contract 9 | */ 10 | interface IMulticall is _IMulticall { 11 | /** 12 | * @notice batch function calls to the contract and return the results of each 13 | * @param data array of function call data payloads 14 | * @return results array of function call results 15 | */ 16 | function multicall( 17 | bytes[] calldata data 18 | ) external returns (bytes[] memory results); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/access/partially_pausable/PartiallyPausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _PartiallyPausable } from './_PartiallyPausable.sol'; 6 | import { IPartiallyPausable } from './IPartiallyPausable.sol'; 7 | 8 | /** 9 | * @title PartiallyPausable security control module. 10 | */ 11 | abstract contract PartiallyPausable is IPartiallyPausable, _PartiallyPausable { 12 | /** 13 | * @inheritdoc IPartiallyPausable 14 | */ 15 | function partiallyPaused(bytes32 key) external view returns (bool status) { 16 | status = _partiallyPaused(key); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/beacon/IBeacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IOwnable } from '../access/ownable/IOwnable.sol'; 6 | import { IERC1967Beacon } from '../interfaces/IERC1967Beacon.sol'; 7 | import { _IBeacon } from './_IBeacon.sol'; 8 | 9 | interface IBeacon is _IBeacon, IERC1967Beacon, IOwnable { 10 | /** 11 | * @notice set the address of the implementation that should be used by BeaconProxy instances 12 | * @param implementationContract address of the implementation contract 13 | */ 14 | function setImplementation(address implementationContract) external; 15 | } 16 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/readable/IDiamondProxyReadable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2535DiamondLoupe } from '../../../interfaces/IERC2535DiamondLoupe.sol'; 6 | import { IIntrospectable } from '../../../introspection/IIntrospectable.sol'; 7 | import { _IDiamondProxyReadable } from './_IDiamondProxyReadable.sol'; 8 | 9 | /** 10 | * @title Diamond proxy introspection interface 11 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 12 | */ 13 | interface IDiamondProxyReadable is 14 | _IDiamondProxyReadable, 15 | IERC2535DiamondLoupe, 16 | IIntrospectable 17 | {} 18 | -------------------------------------------------------------------------------- /contracts/token/fungible/vault/IFungibleVaultToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC4626 } from '../../../interfaces/IERC4626.sol'; 6 | import { IFungibleTokenMetadata } from '../../fungible/metadata/IFungibleTokenMetadata.sol'; 7 | import { IFungibleToken } from '../IFungibleToken.sol'; 8 | import { _IFungibleVaultToken } from './_IFungibleVaultToken.sol'; 9 | 10 | /** 11 | * @title FungibleVaultToken base interface 12 | */ 13 | interface IFungibleVaultToken is 14 | _IFungibleVaultToken, 15 | IFungibleToken, 16 | IFungibleTokenMetadata, 17 | IERC4626 18 | {} 19 | -------------------------------------------------------------------------------- /abi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@solidstate/abi", 3 | "version": "1.0.0-next.2", 4 | "description": "ABIs for Solidstate contracts", 5 | "keywords": [ 6 | "solidity", 7 | "smart-contracts", 8 | "ethereum", 9 | "ether", 10 | "eth", 11 | "cryptocurrency", 12 | "crypto", 13 | "wow", 14 | "library", 15 | "hardhat", 16 | "buidler" 17 | ], 18 | "repository": "github:solidstate-network/solidstate-solidity", 19 | "license": "MIT", 20 | "author": "Nick Barry", 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "gitHead": "edd6391ae61d9e82fe0464f179ca55b746da8806" 25 | } 26 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC2771.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2771 } from './_IERC2771.sol'; 6 | 7 | /** 8 | * @title ERC2771 interface 9 | * @dev see https://eips.ethereum.org/EIPS/eip-2771 10 | */ 11 | interface IERC2771 is _IERC2771 { 12 | /** 13 | * @notice query whether account is a trusted ERC2771 forwarder 14 | * @param account address to query 15 | * @return trustedStatus whether account is a trusted forwarder 16 | */ 17 | function isTrustedForwarder( 18 | address account 19 | ) external view returns (bool trustedStatus); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/readable/_IDiamondProxyReadable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2535DiamondLoupe } from '../../../interfaces/_IERC2535DiamondLoupe.sol'; 6 | import { _IIntrospectable } from '../../../introspection/_IIntrospectable.sol'; 7 | import { _IDiamondProxy } from '../_IDiamondProxy.sol'; 8 | 9 | /** 10 | * @title Diamond proxy introspection interface needed for internal functions 11 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 12 | */ 13 | interface _IDiamondProxyReadable is 14 | _IERC2535DiamondLoupe, 15 | _IDiamondProxy, 16 | _IIntrospectable 17 | {} 18 | -------------------------------------------------------------------------------- /spec/proxy/beacon/BeaconProxy.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { describeBehaviorOfProxy, ProxyBehaviorArgs } from '@solidstate/spec'; 3 | import { IBeaconProxy } from '@solidstate/typechain-types'; 4 | 5 | export interface BeaconProxyBehaviorArgs extends ProxyBehaviorArgs {} 6 | 7 | export function describeBehaviorOfBeaconProxy( 8 | deploy: () => Promise, 9 | args: BeaconProxyBehaviorArgs, 10 | skips?: string[], 11 | ) { 12 | const describe = describeFilter(skips); 13 | 14 | describe('::BeaconProxy', () => { 15 | describeBehaviorOfProxy(deploy, args, skips); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/token/fungible/vault/_IFungibleVaultToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC4626 } from '../../../interfaces/_IERC4626.sol'; 6 | import { _IFungibleTokenMetadata } from '../metadata/_IFungibleTokenMetadata.sol'; 7 | import { _IFungibleToken } from '../_IFungibleToken.sol'; 8 | 9 | /** 10 | * @title FungibleVaultToken base interface 11 | */ 12 | interface _IFungibleVaultToken is 13 | _IFungibleToken, 14 | _IFungibleTokenMetadata, 15 | _IERC4626 16 | { 17 | error FungibleVaultToken__MaximumAmountExceeded(); 18 | error FungibleVaultToken__AllowanceExceeded(); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/introspection/Introspectable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC165 } from '../interfaces/IERC165.sol'; 6 | import { _Introspectable } from './_Introspectable.sol'; 7 | import { IIntrospectable } from './IIntrospectable.sol'; 8 | 9 | /** 10 | * @title ERC165 implementation 11 | */ 12 | abstract contract Introspectable is IIntrospectable, _Introspectable { 13 | /** 14 | * @inheritdoc IERC165 15 | */ 16 | function supportsInterface( 17 | bytes4 interfaceId 18 | ) external view returns (bool) { 19 | return _supportsInterface(interfaceId); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/test/TransientSlotTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { tslot } from '../data/TransientSlot.sol'; 6 | 7 | contract TransientSlotTest { 8 | function transientWriteTest( 9 | tslot slot, 10 | bytes32 input 11 | ) external returns (bytes32 output) { 12 | slot.write(input); 13 | output = slot.read(); 14 | } 15 | 16 | function transientClearTest( 17 | tslot slot, 18 | bytes32 input 19 | ) external returns (bytes32 output) { 20 | slot.write(input); 21 | slot.clear(); 22 | output = slot.read(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/ISolidstateNonFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { INonFungibleTokenEnumerable } from './enumerable/INonFungibleTokenEnumerable.sol'; 6 | import { INonFungibleTokenMetadata } from './metadata/INonFungibleTokenMetadata.sol'; 7 | import { _ISolidstateNonFungibleToken } from './_ISolidstateNonFungibleToken.sol'; 8 | import { INonFungibleToken } from './INonFungibleToken.sol'; 9 | 10 | interface ISolidstateNonFungibleToken is 11 | _ISolidstateNonFungibleToken, 12 | INonFungibleToken, 13 | INonFungibleTokenEnumerable, 14 | INonFungibleTokenMetadata 15 | {} 16 | -------------------------------------------------------------------------------- /patches/typechain.patch: -------------------------------------------------------------------------------- 1 | diff --git a/dist/codegen/normalizeDirName.js b/dist/codegen/normalizeDirName.js 2 | index a86f6a23aadcff6dc792f32f99eef5dd56d79426..e38a088d9a89a10be11b24729755bde2d74b90ae 100644 3 | --- a/dist/codegen/normalizeDirName.js 4 | +++ b/dist/codegen/normalizeDirName.js 5 | @@ -9,6 +9,7 @@ function normalizeDirName(rawName) { 6 | const transformations = [ 7 | (s) => (0, lodash_1.camelCase)(s), 8 | (s) => s.replace(/^\d/g, (match) => '_' + match), // prepend '_' if contains a leading number 9 | + (s) => `${rawName.match(/_*/)[0]}${s}` 10 | ]; 11 | return transformations.reduce((s, t) => t(s), rawName); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC2535DiamondCut.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | /** 8 | * @title ERC2535 write interface for internal functions 9 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 10 | */ 11 | interface _IERC2535DiamondCut is _IERC165 { 12 | enum FacetCutAction { 13 | ADD, 14 | REPLACE, 15 | REMOVE 16 | } 17 | 18 | struct FacetCut { 19 | address target; 20 | FacetCutAction action; 21 | bytes4[] selectors; 22 | } 23 | 24 | event DiamondCut(FacetCut[] facetCuts, address target, bytes data); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/token/fungible/permit/_IFungibleTokenPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2612 } from '../../../interfaces/_IERC2612.sol'; 6 | import { _IERC5267 } from '../../../interfaces/_IERC5267.sol'; 7 | import { _IFungibleTokenMetadata } from '../metadata/_IFungibleTokenMetadata.sol'; 8 | import { _IFungibleToken } from '../_IFungibleToken.sol'; 9 | 10 | interface _IFungibleTokenPermit is 11 | _IFungibleToken, 12 | _IFungibleTokenMetadata, 13 | _IERC2612, 14 | _IERC5267 15 | { 16 | error FungibleTokenPermit__ExpiredDeadline(); 17 | error FungibleTokenPermit__InvalidSignature(); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/TransparentProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Proxy } from '../_Proxy.sol'; 6 | import { Proxy } from '../Proxy.sol'; 7 | import { _TransparentProxy } from './_TransparentProxy.sol'; 8 | import { ITransparentProxy } from './ITransparentProxy.sol'; 9 | 10 | /** 11 | * @title Proxy with upgradeable implementation controlled by ERC171 owner 12 | */ 13 | abstract contract TransparentProxy is 14 | ITransparentProxy, 15 | _TransparentProxy, 16 | Proxy 17 | { 18 | function _fallback() internal virtual override(_Proxy, _TransparentProxy) { 19 | super._fallback(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/_ISolidstateNonFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _INonFungibleTokenEnumerable } from './enumerable/_INonFungibleTokenEnumerable.sol'; 6 | import { _INonFungibleTokenMetadata } from './metadata/_INonFungibleTokenMetadata.sol'; 7 | import { _INonFungibleToken } from './_INonFungibleToken.sol'; 8 | 9 | interface _ISolidstateNonFungibleToken is 10 | _INonFungibleToken, 11 | _INonFungibleTokenEnumerable, 12 | _INonFungibleTokenMetadata 13 | { 14 | error SolidstateNonFungibleToken__PayableApproveNotSupported(); 15 | error SolidstateNonFungibleToken__PayableTransferNotSupported(); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC173.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC173 } from './_IERC173.sol'; 6 | import { IERC5313 } from './IERC5313.sol'; 7 | 8 | /** 9 | * @title Contract ownership standard interface 10 | * @dev see https://eips.ethereum.org/EIPS/eip-173 11 | */ 12 | interface IERC173 is _IERC173, IERC5313 { 13 | /** 14 | * @inheritdoc IERC5313 15 | */ 16 | function owner() external view returns (address owner); 17 | 18 | /** 19 | * @notice transfer contract ownership to new account 20 | * @param account address of new owner 21 | */ 22 | function transferOwnership(address account) external; 23 | } 24 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/ISolidstateDiamondProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IDiamondProxyFallback } from './fallback/IDiamondProxyFallback.sol'; 6 | import { IDiamondProxyReadable } from './readable/IDiamondProxyReadable.sol'; 7 | import { IDiamondProxyWritable } from './writable/IDiamondProxyWritable.sol'; 8 | import { _ISolidstateDiamondProxy } from './_ISolidstateDiamondProxy.sol'; 9 | import { IDiamondProxy } from './IDiamondProxy.sol'; 10 | 11 | interface ISolidstateDiamondProxy is 12 | _ISolidstateDiamondProxy, 13 | IDiamondProxy, 14 | IDiamondProxyFallback, 15 | IDiamondProxyReadable, 16 | IDiamondProxyWritable 17 | {} 18 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/diamond/DiamondBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { BeaconProxy } from '../BeaconProxy.sol'; 6 | import { _DiamondBeaconProxy } from './_DiamondBeaconProxy.sol'; 7 | import { IDiamondBeaconProxy } from './IDiamondBeaconProxy.sol'; 8 | 9 | abstract contract DiamondBeaconProxy is 10 | IDiamondBeaconProxy, 11 | _DiamondBeaconProxy, 12 | BeaconProxy 13 | { 14 | function _getImplementation() 15 | internal 16 | view 17 | override(BeaconProxy, _DiamondBeaconProxy) 18 | returns (address implementation) 19 | { 20 | implementation = super._getImplementation(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/token/fungible/ISolidstateFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IFungibleTokenExtended } from './extended/IFungibleTokenExtended.sol'; 6 | import { IFungibleTokenMetadata } from './metadata/IFungibleTokenMetadata.sol'; 7 | import { IFungibleTokenPermit } from './permit/IFungibleTokenPermit.sol'; 8 | import { _ISolidstateFungibleToken } from './_ISolidstateFungibleToken.sol'; 9 | import { IFungibleToken } from './IFungibleToken.sol'; 10 | 11 | interface ISolidstateFungibleToken is 12 | _ISolidstateFungibleToken, 13 | IFungibleToken, 14 | IFungibleTokenExtended, 15 | IFungibleTokenMetadata, 16 | IFungibleTokenPermit 17 | {} 18 | -------------------------------------------------------------------------------- /contracts/token/multi/metadata/MultiTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1155Metadata } from '../../../interfaces/IERC1155Metadata.sol'; 6 | import { _MultiTokenMetadata } from './_MultiTokenMetadata.sol'; 7 | import { IMultiTokenMetadata } from './IMultiTokenMetadata.sol'; 8 | 9 | /** 10 | * @title MultiToken metadata extensions 11 | */ 12 | abstract contract MultiTokenMetadata is 13 | IMultiTokenMetadata, 14 | _MultiTokenMetadata 15 | { 16 | /** 17 | * @inheritdoc IERC1155Metadata 18 | */ 19 | function uri(uint256 tokenId) external view returns (string memory) { 20 | return _uri(tokenId); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC721.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | /** 8 | * @title Partial ERC721 interface needed by internal functions 9 | */ 10 | interface _IERC721 is _IERC165 { 11 | event Transfer( 12 | address indexed from, 13 | address indexed to, 14 | uint256 indexed tokenId 15 | ); 16 | 17 | event Approval( 18 | address indexed owner, 19 | address indexed operator, 20 | uint256 indexed tokenId 21 | ); 22 | 23 | event ApprovalForAll( 24 | address indexed owner, 25 | address indexed operator, 26 | bool approved 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC4626.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC20 } from './_IERC20.sol'; 6 | import { _IERC20Metadata } from './_IERC20Metadata.sol'; 7 | 8 | /** 9 | * @title Partial ERC4626 interface needed by internal functions 10 | */ 11 | interface _IERC4626 is _IERC20, _IERC20Metadata { 12 | event Deposit( 13 | address indexed caller, 14 | address indexed owner, 15 | uint256 assets, 16 | uint256 shares 17 | ); 18 | 19 | event Withdraw( 20 | address indexed caller, 21 | address indexed receiver, 22 | address indexed owner, 23 | uint256 assets, 24 | uint256 shares 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /lib/sign_data.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 2 | import { ethers } from 'hardhat'; 3 | 4 | export interface SignDataArgs { 5 | types: string[]; 6 | values: any[]; 7 | nonce: any; 8 | address: any; 9 | } 10 | 11 | export function hashData({ types, values, nonce, address }: SignDataArgs) { 12 | const hash = ethers.solidityPackedKeccak256( 13 | [...types, 'uint256', 'address'], 14 | [...values, nonce, address], 15 | ); 16 | 17 | return ethers.getBytes(hash); 18 | } 19 | 20 | export async function signData(signer: SignerWithAddress, data: SignDataArgs) { 21 | const signature = await signer.signMessage(hashData(data)); 22 | 23 | return ethers.getBytes(signature); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC721Metadata } from './_IERC721Metadata.sol'; 6 | 7 | interface IERC721Metadata is _IERC721Metadata { 8 | /** 9 | * @notice get token name 10 | * @return token name 11 | */ 12 | function name() external view returns (string memory); 13 | 14 | /** 15 | * @notice get token symbol 16 | * @return token symbol 17 | */ 18 | function symbol() external view returns (string memory); 19 | 20 | /** 21 | * @notice get generated URI for given token 22 | * @return token URI 23 | */ 24 | function tokenURI(uint256 tokenId) external view returns (string memory); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@solidstate/contracts", 3 | "version": "1.0.0-next.2", 4 | "description": "Solidity library for flexible smart contract development", 5 | "keywords": [ 6 | "solidity", 7 | "smart-contracts", 8 | "ethereum", 9 | "ether", 10 | "eth", 11 | "cryptocurrency", 12 | "crypto", 13 | "wow", 14 | "library", 15 | "hardhat", 16 | "buidler" 17 | ], 18 | "repository": "github:solidstate-network/solidstate-solidity", 19 | "license": "MIT", 20 | "author": "Nick Barry", 21 | "files": [ 22 | "/**/*.sol", 23 | "!/test/" 24 | ], 25 | "publishConfig": { 26 | "access": "public" 27 | }, 28 | "gitHead": "edd6391ae61d9e82fe0464f179ca55b746da8806" 29 | } 30 | -------------------------------------------------------------------------------- /spec/proxy/beacon/diamond/DiamondBeaconProxy.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { 3 | describeBehaviorOfBeaconProxy, 4 | BeaconProxyBehaviorArgs, 5 | } from '@solidstate/spec'; 6 | import { IDiamondBeaconProxy } from '@solidstate/typechain-types'; 7 | 8 | export interface DiamondBeaconProxyBehaviorArgs 9 | extends BeaconProxyBehaviorArgs {} 10 | 11 | export function describeBehaviorOfDiamondBeaconProxy( 12 | deploy: () => Promise, 13 | args: DiamondBeaconProxyBehaviorArgs, 14 | skips?: string[], 15 | ) { 16 | const describe = describeFilter(skips); 17 | 18 | describe('::DiamondBeaconProxy', () => { 19 | describeBehaviorOfBeaconProxy(deploy, args, skips); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC20Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC20Metadata } from './_IERC20Metadata.sol'; 6 | 7 | interface IERC20Metadata is _IERC20Metadata { 8 | /** 9 | * @notice return token name 10 | * @return token name 11 | */ 12 | function name() external view returns (string memory); 13 | 14 | /** 15 | * @notice return token symbol 16 | * @return token symbol 17 | */ 18 | function symbol() external view returns (string memory); 19 | 20 | /** 21 | * @notice return token decimals, generally used only for display purposes 22 | * @return token decimals 23 | */ 24 | function decimals() external view returns (uint8); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IWETH } from './_IWETH.sol'; 6 | import { IERC20 } from './IERC20.sol'; 7 | import { IERC20Metadata } from './IERC20Metadata.sol'; 8 | 9 | /** 10 | * @title WETH (Wrapped ETH) interface 11 | */ 12 | interface IWETH is _IWETH, IERC20, IERC20Metadata { 13 | /** 14 | * @notice convert ETH to WETH 15 | */ 16 | function deposit() external payable; 17 | 18 | /** 19 | * @notice convert WETH to ETH 20 | * @dev if caller is a contract, it should have a fallback or receive function 21 | * @param amount quantity of WETH to convert, denominated in wei 22 | */ 23 | function withdraw(uint256 amount) external; 24 | } 25 | -------------------------------------------------------------------------------- /contracts/access/ownable/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC173 } from '../../interfaces/IERC173.sol'; 6 | import { Context } from '../../meta/Context.sol'; 7 | import { _Ownable } from './_Ownable.sol'; 8 | import { IOwnable } from './IOwnable.sol'; 9 | 10 | /** 11 | * @title Ownership access control based on ERC173 12 | */ 13 | abstract contract Ownable is IOwnable, _Ownable, Context { 14 | /** 15 | * @inheritdoc IERC173 16 | */ 17 | function owner() external view returns (address) { 18 | return _owner(); 19 | } 20 | 21 | /** 22 | * @inheritdoc IERC173 23 | */ 24 | function transferOwnership(address account) external { 25 | _transferOwnership(account); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/BeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Proxy } from '../_Proxy.sol'; 6 | import { Proxy } from '../Proxy.sol'; 7 | import { _BeaconProxy } from './_BeaconProxy.sol'; 8 | import { IBeaconProxy } from './IBeaconProxy.sol'; 9 | 10 | /** 11 | * @title Proxy with externally controlled implementation 12 | * @dev implementation fetched using immutable function selector 13 | */ 14 | abstract contract BeaconProxy is IBeaconProxy, _BeaconProxy, Proxy { 15 | function _getImplementation() 16 | internal 17 | view 18 | virtual 19 | override(_Proxy, _BeaconProxy) 20 | returns (address implementation) 21 | { 22 | implementation = super._getImplementation(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/token/common/royalty/NFTRoyalty.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2981 } from '../../../interfaces/IERC2981.sol'; 6 | import { Introspectable } from '../../../introspection/Introspectable.sol'; 7 | import { _NFTRoyalty } from './_NFTRoyalty.sol'; 8 | import { INFTRoyalty } from './INFTRoyalty.sol'; 9 | 10 | /** 11 | * @title NFTRoyalty implementation 12 | */ 13 | abstract contract NFTRoyalty is INFTRoyalty, _NFTRoyalty, Introspectable { 14 | /** 15 | * @inheritdoc IERC2981 16 | */ 17 | function royaltyInfo( 18 | uint256 tokenId, 19 | uint256 salePrice 20 | ) external view returns (address receiver, uint256 royaltyAmount) { 21 | return _royaltyInfo(tokenId, salePrice); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /patches/@typechain__hardhat.patch: -------------------------------------------------------------------------------- 1 | diff --git a/dist/index.js b/dist/index.js 2 | index 9f14a06b2803cb9fe7cda723da17cfd8fb5526b9..6f0f8a7af7e5d26e08a87a1aa1fb37c07c4015a0 100644 3 | --- a/dist/index.js 4 | +++ b/dist/index.js 5 | @@ -72,7 +72,7 @@ const taskArgsStore = { noTypechain: false, fullRebuild: false }; 6 | } 7 | const cwd = config.paths.root; 8 | const { glob } = await Promise.resolve().then(() => __importStar(require('typechain'))); 9 | - const allFiles = glob(cwd, [`${config.paths.artifacts}/!(build-info)/**/+([a-zA-Z0-9_]).json`]); 10 | + const allFiles = glob(cwd, [`${config.paths.artifacts}/!(build-info)/**/+([a-zA-Z0-9_$]).json`]); 11 | if (typechainCfg.externalArtifacts) { 12 | allFiles.push(...glob(cwd, typechainCfg.externalArtifacts, false)); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/ContractSigner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1271 } from '../../interfaces/IERC1271.sol'; 6 | import { _ContractSigner } from './_ContractSigner.sol'; 7 | import { IContractSigner } from './IContractSigner.sol'; 8 | 9 | /** 10 | * @title Base implementation of ERC1721 11 | * @dev _isValidSignature function must be overridden with application-specific logic 12 | */ 13 | abstract contract ContractSigner is IContractSigner, _ContractSigner { 14 | /** 15 | * @inheritdoc IERC1271 16 | */ 17 | function isValidSignature( 18 | bytes32 hash, 19 | bytes memory signature 20 | ) external view returns (bytes4) { 21 | return _isValidSignature(hash, signature); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/test/BoolTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { Bool } from '../utils/Bool.sol'; 6 | 7 | contract BoolTest { 8 | function sanitizeBytes32Test( 9 | bool input 10 | ) external pure returns (bytes32 output) { 11 | // contaminate the higher-order bits 12 | assembly { 13 | input := or(input, shl(1, not(1))) 14 | } 15 | 16 | output = Bool.toBytes32(input); 17 | } 18 | 19 | function sanitizeUint256Test( 20 | bool input 21 | ) external pure returns (uint256 output) { 22 | // contaminate the higher-order bits 23 | assembly { 24 | input := or(input, shl(1, not(1))) 25 | } 26 | 27 | output = Bool.toUint256(input); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /spec/access/pausable/Pausable.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { Pausable } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | 5 | export interface PausableBehaviorArgs {} 6 | 7 | export function describeBehaviorOfPausable( 8 | deploy: () => Promise, 9 | args: PausableBehaviorArgs, 10 | skips?: string[], 11 | ) { 12 | const describe = describeFilter(skips); 13 | 14 | describe('::Pausable', () => { 15 | let instance: Pausable; 16 | 17 | beforeEach(async () => { 18 | instance = await deploy(); 19 | }); 20 | 21 | describe('#paused()', () => { 22 | it('returns paused == false', async () => { 23 | expect(await instance.paused()).to.equal(false); 24 | }); 25 | }); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/token/fungible/_SolidstateFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _FungibleTokenExtended } from './extended/_FungibleTokenExtended.sol'; 6 | import { _FungibleTokenMetadata } from './metadata/_FungibleTokenMetadata.sol'; 7 | import { _FungibleTokenPermit } from './permit/_FungibleTokenPermit.sol'; 8 | import { _FungibleToken } from './_FungibleToken.sol'; 9 | import { _ISolidstateFungibleToken } from './_ISolidstateFungibleToken.sol'; 10 | 11 | /** 12 | * @title Solidstate FungibleToken implementation, including recommended extensions 13 | */ 14 | abstract contract _SolidstateFungibleToken is 15 | _ISolidstateFungibleToken, 16 | _FungibleToken, 17 | _FungibleTokenExtended, 18 | _FungibleTokenMetadata, 19 | _FungibleTokenPermit 20 | {} 21 | -------------------------------------------------------------------------------- /slippy.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | curly: 'off', 4 | 'explicit-types': 'error', 5 | 'id-denylist': 'error', 6 | 'imports-on-top': 'error', 7 | 'max-state-vars': 'error', 8 | 'named-return-params': 'error', 9 | 'naming-convention': 'off', 10 | 'no-console': 'error', 11 | 'no-default-visibility': 'error', 12 | 'no-duplicate-imports': 'error', 13 | 'no-empty-blocks': 'off', 14 | 'no-global-imports': 'error', 15 | 'no-restricted-syntax': 'error', 16 | 'no-send': 'error', 17 | 'no-tx-origin': 'error', 18 | 'no-uninitialized-immutable-references': 'error', 19 | 'no-unused-vars': 'error', 20 | 'private-vars': 'off', 21 | 'require-revert-reason': 'error', 22 | 'sort-imports': 'error', 23 | 'sort-modifiers': 'error', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /contracts/beacon/diamond/IDiamondBeacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IOwnable } from '../../access/ownable/IOwnable.sol'; 6 | import { IDiamondProxyWritable } from '../../proxy/diamond/writable/IDiamondProxyWritable.sol'; 7 | import { _IDiamondBeacon } from './_IDiamondBeacon.sol'; 8 | 9 | interface IDiamondBeacon is _IDiamondBeacon, IDiamondProxyWritable, IOwnable { 10 | /** 11 | * @notice query the address of the implementation that should be used by IERC1967Proxy instances 12 | * @param selector function selector whose implementation to query 13 | * @return implementation address of the implementation contract 14 | */ 15 | function implementation( 16 | bytes4 selector 17 | ) external view returns (address implementation); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/token/fungible/_IFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC20 } from '../../interfaces/_IERC20.sol'; 6 | import { _IContext } from '../../meta/_IContext.sol'; 7 | 8 | /** 9 | * @title FungibleToken base interface 10 | */ 11 | interface _IFungibleToken is _IERC20, _IContext { 12 | error FungibleToken__ApproveFromZeroAddress(); 13 | error FungibleToken__ApproveToZeroAddress(); 14 | error FungibleToken__BurnExceedsBalance(); 15 | error FungibleToken__BurnFromZeroAddress(); 16 | error FungibleToken__InsufficientAllowance(); 17 | error FungibleToken__MintToZeroAddress(); 18 | error FungibleToken__TransferExceedsBalance(); 19 | error FungibleToken__TransferFromZeroAddress(); 20 | error FungibleToken__TransferToZeroAddress(); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/interfaces/_IERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC165 } from './_IERC165.sol'; 6 | 7 | /** 8 | * @title Partial ERC1155 interface needed by internal functions 9 | */ 10 | interface _IERC1155 is _IERC165 { 11 | event TransferSingle( 12 | address indexed operator, 13 | address indexed from, 14 | address indexed to, 15 | uint256 id, 16 | uint256 value 17 | ); 18 | 19 | event TransferBatch( 20 | address indexed operator, 21 | address indexed from, 22 | address indexed to, 23 | uint256[] ids, 24 | uint256[] values 25 | ); 26 | 27 | event ApprovalForAll( 28 | address indexed account, 29 | address indexed operator, 30 | bool approved 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/writable/_DiamondProxyWritable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Introspectable } from '../../../introspection/_Introspectable.sol'; 6 | import { _DiamondProxy } from '../_DiamondProxy.sol'; 7 | import { _IDiamondProxyWritable } from './_IDiamondProxyWritable.sol'; 8 | 9 | abstract contract _DiamondProxyWritable is 10 | _IDiamondProxyWritable, 11 | _DiamondProxy, 12 | _Introspectable 13 | { 14 | /** 15 | * TODO: standardize use of externally accessible functions with "External" suffix 16 | */ 17 | function _diamondCutExternal( 18 | FacetCut[] memory facetCuts, 19 | address target, 20 | bytes memory data 21 | ) internal virtual onlyProxyAdmin { 22 | _diamondCut(facetCuts, target, data); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/utils/Block.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 2 | import { time } from '@nomicfoundation/hardhat-network-helpers'; 3 | import { $Block, $Block__factory } from '@solidstate/typechain-types'; 4 | import { expect } from 'chai'; 5 | import { ethers } from 'hardhat'; 6 | 7 | describe('Block', async () => { 8 | let deployer: SignerWithAddress; 9 | let instance: $Block; 10 | 11 | before(async () => { 12 | [deployer] = await ethers.getSigners(); 13 | instance = await new $Block__factory(deployer).deploy(); 14 | }); 15 | 16 | describe('#timestamp()', () => { 17 | it('returns current timestamp', async () => { 18 | const timestamp = BigInt(await time.latest()); 19 | 20 | expect(await instance.$timestamp.staticCall()).to.eq(timestamp); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /contracts/beacon/Beacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { Ownable } from '../access/ownable/Ownable.sol'; 6 | import { IERC1967Beacon } from '../interfaces/IERC1967Beacon.sol'; 7 | import { _Beacon } from './_Beacon.sol'; 8 | import { IBeacon } from './IBeacon.sol'; 9 | 10 | contract Beacon is IBeacon, _Beacon, Ownable { 11 | /** 12 | * @inheritdoc IERC1967Beacon 13 | */ 14 | function implementation() 15 | external 16 | view 17 | returns (address implementationContract) 18 | { 19 | implementationContract = _implementation(); 20 | } 21 | 22 | /** 23 | * @inheritdoc IBeacon 24 | */ 25 | function setImplementation(address implementationContract) external { 26 | _setImplementation(implementationContract); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/fallback/IDiamondProxyFallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IDiamondProxy } from '../IDiamondProxy.sol'; 6 | import { _IDiamondProxyFallback } from './_IDiamondProxyFallback.sol'; 7 | 8 | interface IDiamondProxyFallback is _IDiamondProxyFallback, IDiamondProxy { 9 | /** 10 | * @notice query the address of the fallback implementation 11 | * @return fallbackAddress address of fallback implementation 12 | */ 13 | function getFallbackAddress() 14 | external 15 | view 16 | returns (address fallbackAddress); 17 | 18 | /** 19 | * @notice set the address of the fallback implementation 20 | * @param fallbackAddress address of fallback implementation 21 | */ 22 | function setFallbackAddress(address fallbackAddress) external; 23 | } 24 | -------------------------------------------------------------------------------- /contracts/utils/Bool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | library Bool { 6 | /** 7 | * @notice sanitize higher-order bits of bool and convert to bytes32 8 | * @param value bool to convert to bytes32 9 | * @return result bytes32 representation of bool 10 | */ 11 | function toBytes32(bool value) internal pure returns (bytes32 result) { 12 | assembly { 13 | result := iszero(iszero(value)) 14 | } 15 | } 16 | 17 | function toUint256(bool value) internal pure returns (uint256 result) { 18 | assembly { 19 | result := iszero(iszero(value)) 20 | } 21 | } 22 | 23 | function xor(bool value0, bool value1) internal pure returns (bool result) { 24 | assembly { 25 | result := xor(value0, value1) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/token/non_fungible/enumerable/NonFungibleTokenEnumerable.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfNonFungibleTokenEnumerable } from '@solidstate/spec'; 2 | import { 3 | $NonFungibleTokenEnumerable, 4 | $NonFungibleTokenEnumerable__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | describe('NonFungibleTokenEnumerable', () => { 9 | let instance: $NonFungibleTokenEnumerable; 10 | 11 | beforeEach(async () => { 12 | const [deployer] = await ethers.getSigners(); 13 | instance = await new $NonFungibleTokenEnumerable__factory( 14 | deployer, 15 | ).deploy(); 16 | }); 17 | 18 | describeBehaviorOfNonFungibleTokenEnumerable(async () => instance, { 19 | mint: (recipient, tokenId) => instance.$_mint(recipient, tokenId), 20 | burn: (tokenId) => instance.$_burn(tokenId), 21 | supply: 0n, 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /contracts/access/access_control/_IAccessControl.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IContext } from '../../meta/_IContext.sol'; 6 | 7 | /** 8 | * @title Partial AccessControl interface needed by internal functions 9 | */ 10 | interface _IAccessControl is _IContext { 11 | event RoleAdminChanged( 12 | bytes32 indexed role, 13 | bytes32 indexed previousAdminRole, 14 | bytes32 indexed newAdminRole 15 | ); 16 | 17 | event RoleGranted( 18 | bytes32 indexed role, 19 | address indexed account, 20 | address indexed sender 21 | ); 22 | 23 | event RoleRevoked( 24 | bytes32 indexed role, 25 | address indexed account, 26 | address indexed sender 27 | ); 28 | 29 | error AccessControl__Unauthorized(bytes32 role, address account); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/diamond/_DiamondBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IDiamondBeacon } from '../../../beacon/diamond/IDiamondBeacon.sol'; 6 | import { _BeaconProxy } from '../_BeaconProxy.sol'; 7 | import { _IDiamondBeaconProxy } from './_IDiamondBeaconProxy.sol'; 8 | 9 | abstract contract _DiamondBeaconProxy is _IDiamondBeaconProxy, _BeaconProxy { 10 | function _getImplementation() 11 | internal 12 | view 13 | virtual 14 | override 15 | returns (address implementation) 16 | { 17 | implementation = _getImplementation(msg.sig); 18 | } 19 | 20 | function _getImplementation( 21 | bytes4 sig 22 | ) internal view virtual returns (address implementation) { 23 | implementation = IDiamondBeacon(_getBeacon()).implementation(sig); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC2535DiamondCut.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2535DiamondCut } from './_IERC2535DiamondCut.sol'; 6 | import { IERC165 } from './IERC165.sol'; 7 | 8 | /** 9 | * @title ERC2535 write interface 10 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 11 | */ 12 | interface IERC2535DiamondCut is _IERC2535DiamondCut, IERC165 { 13 | /** 14 | * @notice update diamond facets and optionally execute arbitrary initialization function 15 | * @param facetCuts array of structured Diamond facet update data 16 | * @param target optional target of initialization delegatecall 17 | * @param data optional initialization function call data 18 | */ 19 | function diamondCut( 20 | FacetCut[] calldata facetCuts, 21 | address target, 22 | bytes calldata data 23 | ) external; 24 | } 25 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC2981.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2981 } from './_IERC2981.sol'; 6 | import { IERC165 } from './IERC165.sol'; 7 | 8 | /** 9 | * @title ERC2981 interface 10 | * @dev see https://eips.ethereum.org/EIPS/eip-2981 11 | */ 12 | interface IERC2981 is _IERC2981, IERC165 { 13 | /** 14 | * @notice called with the sale price to determine how much royalty is owed and to whom 15 | * @param tokenId the ERC721 or ERC1155 token id to query for royalty information 16 | * @param salePrice the sale price of the given asset 17 | * @return receiver rightful recipient of royalty 18 | * @return royaltyAmount amount of royalty owed 19 | */ 20 | function royaltyInfo( 21 | uint256 tokenId, 22 | uint256 salePrice 23 | ) external view returns (address receiver, uint256 royaltyAmount); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/token/fungible/SolidstateFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { FungibleTokenExtended } from './extended/FungibleTokenExtended.sol'; 6 | import { FungibleTokenMetadata } from './metadata/FungibleTokenMetadata.sol'; 7 | import { FungibleTokenPermit } from './permit/FungibleTokenPermit.sol'; 8 | import { _SolidstateFungibleToken } from './_SolidstateFungibleToken.sol'; 9 | import { FungibleToken } from './FungibleToken.sol'; 10 | import { ISolidstateFungibleToken } from './ISolidstateFungibleToken.sol'; 11 | 12 | /** 13 | * @title Solidstate FungibleToken implementation, including recommended extensions 14 | */ 15 | abstract contract SolidstateFungibleToken is 16 | ISolidstateFungibleToken, 17 | _SolidstateFungibleToken, 18 | FungibleToken, 19 | FungibleTokenExtended, 20 | FungibleTokenMetadata, 21 | FungibleTokenPermit 22 | {} 23 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC3156FlashBorrower.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC3156FlashBorrower } from './_IERC3156FlashBorrower.sol'; 6 | 7 | interface IERC3156FlashBorrower is _IERC3156FlashBorrower { 8 | /** 9 | * @notice Receive a flash loan. 10 | * @param initiator The initiator of the loan. 11 | * @param token The loan currency. 12 | * @param amount The amount of tokens lent. 13 | * @param fee The additional amount of tokens to repay. 14 | * @param data Arbitrary data structure, intended to contain user-defined parameters. 15 | * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" 16 | */ 17 | function onFlashLoan( 18 | address initiator, 19 | address token, 20 | uint256 amount, 21 | uint256 fee, 22 | bytes calldata data 23 | ) external returns (bytes32); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC5267.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC5267 } from './_IERC5267.sol'; 6 | 7 | /** 8 | * @title ERC5267 interface 9 | * @dev see https://eips.ethereum.org/EIPS/eip-5267. 10 | */ 11 | interface IERC5267 is _IERC5267 { 12 | /** 13 | * @notice TODO 14 | * @return fields 15 | * @return name 16 | * @return version 17 | * @return chainId 18 | * @return verifyingContract 19 | * @return salt 20 | * @return extensions 21 | */ 22 | function eip712Domain() 23 | external 24 | view 25 | returns ( 26 | bytes1 fields, 27 | string calldata name, 28 | string calldata version, 29 | uint256 chainId, 30 | address verifyingContract, 31 | bytes32 salt, 32 | uint256[] calldata extensions 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /test/token/fungible/extended/FungibleTokenExtended.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfFungibleTokenExtended } from '@solidstate/spec'; 2 | import { 3 | $FungibleTokenExtended, 4 | $FungibleTokenExtended__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | describe('FungibleTokenExtended', () => { 9 | let instance: $FungibleTokenExtended; 10 | 11 | beforeEach(async () => { 12 | const [deployer] = await ethers.getSigners(); 13 | instance = await new $FungibleTokenExtended__factory(deployer).deploy(); 14 | }); 15 | 16 | describeBehaviorOfFungibleTokenExtended(async () => instance, { 17 | supply: 0n, 18 | mint: (recipient, amount) => instance.$_mint(recipient, amount), 19 | burn: (recipient, amount) => instance.$_burn(recipient, amount), 20 | allowance: (holder, spender) => 21 | instance.$_allowance.staticCall(holder, spender), 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/_IDiamondProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2535DiamondCut } from '../../interfaces/_IERC2535DiamondCut.sol'; 6 | import { _IERC2535DiamondLoupe } from '../../interfaces/_IERC2535DiamondLoupe.sol'; 7 | import { _IProxy } from '../_IProxy.sol'; 8 | 9 | interface _IDiamondProxy is 10 | _IProxy, 11 | _IERC2535DiamondCut, 12 | _IERC2535DiamondLoupe 13 | { 14 | error DiamondProxyWritable__InvalidInitializationParameters(); 15 | error DiamondProxyWritable__RemoveTargetNotZeroAddress(); 16 | error DiamondProxyWritable__ReplaceTargetIsIdentical(); 17 | error DiamondProxyWritable__SelectorAlreadyAdded(); 18 | error DiamondProxyWritable__SelectorIsImmutable(); 19 | error DiamondProxyWritable__SelectorNotFound(); 20 | error DiamondProxyWritable__SelectorNotSpecified(); 21 | error DiamondProxyWritable__TargetHasNoCode(); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/writable/DiamondProxyWritable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2535DiamondCut } from '../../../interfaces/IERC2535DiamondCut.sol'; 6 | import { Introspectable } from '../../../introspection/Introspectable.sol'; 7 | import { _DiamondProxyWritable } from './_DiamondProxyWritable.sol'; 8 | import { IDiamondProxyWritable } from './IDiamondProxyWritable.sol'; 9 | 10 | /** 11 | * @title EIP-2535 "Diamond" proxy update contract 12 | */ 13 | abstract contract DiamondProxyWritable is 14 | IDiamondProxyWritable, 15 | _DiamondProxyWritable, 16 | Introspectable 17 | { 18 | /** 19 | * @inheritdoc IERC2535DiamondCut 20 | */ 21 | function diamondCut( 22 | FacetCut[] calldata facetCuts, 23 | address target, 24 | bytes calldata data 25 | ) external { 26 | _diamondCutExternal(facetCuts, target, data); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@solidstate/library", 3 | "version": "1.0.0-next.2", 4 | "description": "Solidstate utility library", 5 | "keywords": [ 6 | "solidity", 7 | "smart-contracts", 8 | "ethereum", 9 | "ether", 10 | "eth", 11 | "cryptocurrency", 12 | "crypto", 13 | "wow", 14 | "library", 15 | "hardhat", 16 | "buidler" 17 | ], 18 | "repository": "github:solidstate-network/solidstate-solidity", 19 | "license": "MIT", 20 | "author": "Nick Barry", 21 | "main": "./dist/index.js", 22 | "types": "./dist/index.d.ts", 23 | "files": [ 24 | "dist/" 25 | ], 26 | "scripts": { 27 | "build": "pnpm clean && tsc --build tsconfig.json", 28 | "clean": "rm -rf dist/" 29 | }, 30 | "dependencies": { 31 | "ethers5": "npm:ethers@^5.8.0" 32 | }, 33 | "publishConfig": { 34 | "access": "public" 35 | }, 36 | "gitHead": "edd6391ae61d9e82fe0464f179ca55b746da8806" 37 | } 38 | -------------------------------------------------------------------------------- /test/beacon/Beacon.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 2 | import { describeBehaviorOfBeacon } from '@solidstate/spec'; 3 | import { $Beacon, $Beacon__factory } from '@solidstate/typechain-types'; 4 | import { expect } from 'chai'; 5 | import { ethers } from 'hardhat'; 6 | 7 | describe('Beacon', () => { 8 | let owner: SignerWithAddress; 9 | let nonOwner: SignerWithAddress; 10 | let instance: $Beacon; 11 | 12 | before(async () => { 13 | [owner, nonOwner] = await ethers.getSigners(); 14 | }); 15 | 16 | beforeEach(async () => { 17 | const [deployer] = await ethers.getSigners(); 18 | 19 | instance = await new $Beacon__factory(deployer).deploy(); 20 | 21 | await instance.$_setOwner(await owner.getAddress()); 22 | }); 23 | 24 | describeBehaviorOfBeacon(async () => instance, { 25 | getOwner: async () => owner, 26 | getNonOwner: async () => nonOwner, 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /contracts/test/TransientReentrancyGuardTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { TransientReentrancyGuard } from '../access/reentrancy_guard/TransientReentrancyGuard.sol'; 6 | 7 | abstract contract TransientReentrancyGuardTest is TransientReentrancyGuard { 8 | function modifier_nonReentrant() external nonReentrant { 9 | // do nothing 10 | } 11 | 12 | function reentrancyTest() external nonReentrant { 13 | this.reentrancyTest(); 14 | } 15 | 16 | function crossFunctionReentrancyTest() external nonReentrant { 17 | this.reentrancyTest(); 18 | } 19 | 20 | function lockReentrancyGuardTest() external { 21 | _lockReentrancyGuard(); 22 | this.modifier_nonReentrant(); 23 | } 24 | 25 | function unlockReentrancyGuardTest() external nonReentrant { 26 | _unlockReentrancyGuard(); 27 | this.modifier_nonReentrant(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/storage/BeaconStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library BeaconStorage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.Beacon 10 | */ 11 | struct Layout { 12 | address implementation; 13 | } 14 | 15 | sslot internal constant DEFAULT_STORAGE_SLOT = 16 | sslot.wrap( 17 | keccak256( 18 | abi.encode( 19 | uint256(keccak256(bytes('solidstate.layout.Beacon'))) - 1 20 | ) 21 | ) & ~bytes32(uint256(0xff)) 22 | ); 23 | 24 | function layout() internal pure returns (Layout storage $) { 25 | $ = layout(DEFAULT_STORAGE_SLOT); 26 | } 27 | 28 | function layout(sslot slot) internal pure returns (Layout storage $) { 29 | assembly { 30 | $.slot := slot 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC1404.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1404 } from './_IERC1404.sol'; 6 | import { IERC20 } from './IERC20.sol'; 7 | 8 | /** 9 | * @title ERC1404 interface 10 | * @dev see https://eips.ethereum.org/EIPS/eip-1404 11 | */ 12 | interface IERC1404 is _IERC1404, IERC20 { 13 | /** 14 | * @notice return restriction code resulting from given transaction parameters 15 | * @return restriction code (0 if no restriction exists) 16 | */ 17 | function detectTransferRestriction( 18 | address from, 19 | address to, 20 | uint256 amount 21 | ) external view returns (uint8); 22 | 23 | /** 24 | * @notice return the appropriate error message for given restriction code 25 | * @return error message 26 | */ 27 | function messageForTransferRestriction( 28 | uint8 restrictionCode 29 | ) external view returns (string memory); 30 | } 31 | -------------------------------------------------------------------------------- /test/token/fungible/metadata/FungibleTokenMetadata.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfFungibleTokenMetadata } from '@solidstate/spec'; 2 | import { 3 | $FungibleTokenMetadata, 4 | $FungibleTokenMetadata__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | describe('FungibleTokenMetadata', () => { 9 | const name = 'FungibleTokenMetadata.name'; 10 | const symbol = 'FungibleTokenMetadata.symbol'; 11 | const decimals = 18n; 12 | let instance: $FungibleTokenMetadata; 13 | 14 | beforeEach(async () => { 15 | const [deployer] = await ethers.getSigners(); 16 | instance = await new $FungibleTokenMetadata__factory(deployer).deploy(); 17 | 18 | await instance.$_setName(name); 19 | await instance.$_setSymbol(symbol); 20 | await instance.$_setDecimals(decimals); 21 | }); 22 | 23 | describeBehaviorOfFungibleTokenMetadata(async () => instance, { 24 | name, 25 | symbol, 26 | decimals, 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/ITransparentProxyWithAdminFunctions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ITransparentProxyWithAdminFunctions } from './_ITransparentProxyWithAdminFunctions.sol'; 6 | import { ITransparentProxy } from './ITransparentProxy.sol'; 7 | 8 | /** 9 | * @title Utility interface for TransparentProxy which provides access to transparent admin functions 10 | */ 11 | interface ITransparentProxyWithAdminFunctions is 12 | _ITransparentProxyWithAdminFunctions, 13 | ITransparentProxy 14 | { 15 | /** 16 | * @notice update the EIP-1967 proxy admin 17 | * @param admin address of admin account 18 | */ 19 | function setProxyAdmin(address admin) external; 20 | 21 | /** 22 | * @notice update the EIP-1967 logic implementation address 23 | * @param implementation address of implementation contract 24 | */ 25 | function setImplementation(address implementation) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/token/fungible/snapshot/IFungibleTokenSnapshot.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IFungibleTokenSnapshot } from './_IFungibleTokenSnapshot.sol'; 6 | 7 | interface IFungibleTokenSnapshot is _IFungibleTokenSnapshot { 8 | /** 9 | * @notice query the token balance of given account at given snapshot id 10 | * @param account address to query 11 | * @param snapshotId snapshot id to query 12 | * @return balance token balance 13 | */ 14 | function balanceOfAt( 15 | address account, 16 | uint256 snapshotId 17 | ) external view returns (uint256 balance); 18 | 19 | /** 20 | * @notice query the total minted token supply at given snapshot id 21 | * @param snapshotId snapshot id to query 22 | * @return totalSupply token supply 23 | */ 24 | function totalSupplyAt( 25 | uint256 snapshotId 26 | ) external view returns (uint256 totalSupply); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/transparent/ITransparentBeaconProxyWithAdminFunctions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ITransparentBeaconProxyWithAdminFunctions } from './_ITransparentBeaconProxyWithAdminFunctions.sol'; 6 | import { ITransparentBeaconProxy } from './ITransparentBeaconProxy.sol'; 7 | 8 | /** 9 | * @title Utility interface for TransparentBeaconProxy which provides access to transparent admin functions 10 | */ 11 | interface ITransparentBeaconProxyWithAdminFunctions is 12 | _ITransparentBeaconProxyWithAdminFunctions, 13 | ITransparentBeaconProxy 14 | { 15 | /** 16 | * @notice update the EIP-1967 proxy admin 17 | * @param admin address of admin account 18 | */ 19 | function setProxyAdmin(address admin) external; 20 | 21 | /** 22 | * @notice update the EIP-1967 beacon address 23 | * @param beacon beacon contract address 24 | */ 25 | function setBeacon(address beacon) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/storage/ERC1271Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ERC1271Storage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.ERC1271 10 | */ 11 | struct Layout { 12 | mapping(bytes32 hash => bool signedStatus) hashes; 13 | } 14 | 15 | sslot internal constant DEFAULT_STORAGE_SLOT = 16 | sslot.wrap( 17 | keccak256( 18 | abi.encode( 19 | uint256(keccak256(bytes('solidstate.layout.ERC1271'))) - 1 20 | ) 21 | ) & ~bytes32(uint256(0xff)) 22 | ); 23 | 24 | function layout() internal pure returns (Layout storage $) { 25 | $ = layout(DEFAULT_STORAGE_SLOT); 26 | } 27 | 28 | function layout(sslot slot) internal pure returns (Layout storage $) { 29 | assembly { 30 | $.slot := slot 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/access/partially_pausable/PartiallyPausable.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { PartiallyPausable } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | import { ethers } from 'hardhat'; 5 | 6 | export interface PartiallyPausableBehaviorArgs {} 7 | 8 | export function describeBehaviorOfPartiallyPausable( 9 | deploy: () => Promise, 10 | args: PartiallyPausableBehaviorArgs, 11 | skips?: string[], 12 | ) { 13 | const describe = describeFilter(skips); 14 | 15 | describe('::PartiallyPausable', () => { 16 | let instance: PartiallyPausable; 17 | 18 | beforeEach(async () => { 19 | instance = await deploy(); 20 | }); 21 | 22 | describe('#partiallyPaused()', () => { 23 | it('returns paused == false', async () => { 24 | const key = ethers.randomBytes(32); 25 | expect(await instance.partiallyPaused(key)).to.equal(false); 26 | }); 27 | }); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /contracts/token/multi/_IMultiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1155 } from '../../interfaces/_IERC1155.sol'; 6 | import { _IIntrospectable } from '../../introspection/_IIntrospectable.sol'; 7 | import { _IContext } from '../../meta/_IContext.sol'; 8 | 9 | /** 10 | * @title MultiToken base interface 11 | */ 12 | interface _IMultiToken is _IERC1155, _IIntrospectable, _IContext { 13 | error MultiToken__ArrayLengthMismatch(); 14 | error MultiToken__BalanceQueryZeroAddress(); 15 | error MultiToken__NotOwnerOrApproved(); 16 | error MultiToken__SelfApproval(); 17 | error MultiToken__BurnExceedsBalance(); 18 | error MultiToken__BurnFromZeroAddress(); 19 | error MultiToken__ERC1155ReceiverRejected(); 20 | error MultiToken__ERC1155ReceiverNotImplemented(); 21 | error MultiToken__MintToZeroAddress(); 22 | error MultiToken__TransferExceedsBalance(); 23 | error MultiToken__TransferToZeroAddress(); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/utils/_Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IMulticall } from './_IMulticall.sol'; 6 | 7 | abstract contract _Multicall is _IMulticall { 8 | function _multicall( 9 | bytes[] calldata data 10 | ) internal virtual returns (bytes[] memory results) { 11 | results = new bytes[](data.length); 12 | 13 | unchecked { 14 | for (uint256 i; i < data.length; i++) { 15 | (bool success, bytes memory returndata) = address(this) 16 | .delegatecall(data[i]); 17 | 18 | if (success) { 19 | results[i] = returndata; 20 | } else { 21 | assembly { 22 | returndatacopy(0, 0, returndatasize()) 23 | revert(0, returndatasize()) 24 | } 25 | } 26 | } 27 | } 28 | 29 | return results; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/DiamondProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Proxy } from '../_Proxy.sol'; 6 | import { Proxy } from '../Proxy.sol'; 7 | import { _DiamondProxy } from './_DiamondProxy.sol'; 8 | import { IDiamondProxy } from './IDiamondProxy.sol'; 9 | 10 | /** 11 | * @title EIP-2535 "Diamond" proxy base contract 12 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 13 | * @dev note that for EIP-2535 compliance this base contract must also include the DiamondProxyReadable functions (either within the same deployment or by proxy) 14 | */ 15 | contract DiamondProxy is IDiamondProxy, _DiamondProxy, Proxy { 16 | /** 17 | * @inheritdoc _DiamondProxy 18 | */ 19 | function _getImplementation() 20 | internal 21 | view 22 | virtual 23 | override(_Proxy, _DiamondProxy) 24 | returns (address implementation) 25 | { 26 | implementation = super._getImplementation(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/_INonFungibleToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC721 } from '../../interfaces/_IERC721.sol'; 6 | import { _IIntrospectable } from '../../introspection/_IIntrospectable.sol'; 7 | import { _IContext } from '../../meta/_IContext.sol'; 8 | 9 | /** 10 | * @title NonFungibleToken base interface 11 | */ 12 | interface _INonFungibleToken is _IERC721, _IIntrospectable, _IContext { 13 | error NonFungibleToken__NotOwnerOrApproved(); 14 | error NonFungibleToken__SelfApproval(); 15 | error NonFungibleToken__BalanceQueryZeroAddress(); 16 | error NonFungibleToken__ERC721ReceiverNotImplemented(); 17 | error NonFungibleToken__InvalidOwner(); 18 | error NonFungibleToken__MintToZeroAddress(); 19 | error NonFungibleToken__NonExistentToken(); 20 | error NonFungibleToken__NotTokenOwner(); 21 | error NonFungibleToken__TokenAlreadyMinted(); 22 | error NonFungibleToken__TransferToZeroAddress(); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/storage/ERC2771Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ERC2771Storage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.ERC2771 10 | */ 11 | struct Layout { 12 | mapping(address account => bool trustedStatus) trustedForwarders; 13 | } 14 | 15 | sslot internal constant DEFAULT_STORAGE_SLOT = 16 | sslot.wrap( 17 | keccak256( 18 | abi.encode( 19 | uint256(keccak256(bytes('solidstate.layout.ERC2771'))) - 1 20 | ) 21 | ) & ~bytes32(uint256(0xff)) 22 | ); 23 | 24 | function layout() internal pure returns (Layout storage $) { 25 | $ = layout(DEFAULT_STORAGE_SLOT); 26 | } 27 | 28 | function layout(sslot slot) internal pure returns (Layout storage $) { 29 | assembly { 30 | $.slot := slot 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/storage/ERC165Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ERC165Storage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.ERC165 10 | */ 11 | struct Layout { 12 | mapping(bytes4 interfaceId => bool supportStatus) supportedInterfaces; 13 | } 14 | 15 | sslot internal constant DEFAULT_STORAGE_SLOT = 16 | sslot.wrap( 17 | keccak256( 18 | abi.encode( 19 | uint256(keccak256(bytes('solidstate.layout.ERC165'))) - 1 20 | ) 21 | ) & ~bytes32(uint256(0xff)) 22 | ); 23 | 24 | function layout() internal pure returns (Layout storage $) { 25 | $ = layout(DEFAULT_STORAGE_SLOT); 26 | } 27 | 28 | function layout(sslot slot) internal pure returns (Layout storage $) { 29 | assembly { 30 | $.slot := slot 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/token/multi/_SolidstateMultiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _MultiTokenEnumerable } from './enumerable/_MultiTokenEnumerable.sol'; 6 | import { _MultiTokenMetadata } from './metadata/_MultiTokenMetadata.sol'; 7 | import { _ISolidstateMultiToken } from './_ISolidstateMultiToken.sol'; 8 | import { _MultiToken } from './MultiToken.sol'; 9 | 10 | abstract contract _SolidstateMultiToken is 11 | _ISolidstateMultiToken, 12 | _MultiToken, 13 | _MultiTokenEnumerable, 14 | _MultiTokenMetadata 15 | { 16 | /** 17 | * @inheritdoc _MultiToken 18 | */ 19 | function _beforeTokenTransfer( 20 | address operator, 21 | address from, 22 | address to, 23 | uint256[] memory ids, 24 | uint256[] memory amounts, 25 | bytes memory data 26 | ) internal virtual override(_MultiToken, _MultiTokenEnumerable) { 27 | super._beforeTokenTransfer(operator, from, to, ids, amounts, data); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/access/ownable/safe/SafeOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Ownable } from '../_Ownable.sol'; 6 | import { Ownable } from '../Ownable.sol'; 7 | import { _SafeOwnable } from './_SafeOwnable.sol'; 8 | import { ISafeOwnable } from './ISafeOwnable.sol'; 9 | 10 | /** 11 | * @title Ownership access control based on ERC173 with ownership transfer safety check 12 | */ 13 | abstract contract SafeOwnable is ISafeOwnable, _SafeOwnable, Ownable { 14 | /** 15 | * @inheritdoc ISafeOwnable 16 | */ 17 | function nomineeOwner() external view returns (address) { 18 | return _nomineeOwner(); 19 | } 20 | 21 | /** 22 | * @inheritdoc ISafeOwnable 23 | */ 24 | function acceptOwnership() external { 25 | _acceptOwnership(); 26 | } 27 | 28 | function _transferOwnership( 29 | address account 30 | ) internal virtual override(_Ownable, _SafeOwnable) { 31 | super._transferOwnership(account); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/storage/PausableStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library PausableStorage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.Pausable 10 | */ 11 | struct Layout { 12 | bool paused; 13 | mapping(bytes32 key => bool pausedStatus) partiallyPaused; 14 | } 15 | 16 | sslot internal constant DEFAULT_STORAGE_SLOT = 17 | sslot.wrap( 18 | keccak256( 19 | abi.encode( 20 | uint256(keccak256(bytes('solidstate.layout.Pausable'))) - 1 21 | ) 22 | ) & ~bytes32(uint256(0xff)) 23 | ); 24 | 25 | function layout() internal pure returns (Layout storage $) { 26 | $ = layout(DEFAULT_STORAGE_SLOT); 27 | } 28 | 29 | function layout(sslot slot) internal pure returns (Layout storage $) { 30 | assembly { 31 | $.slot := slot 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/transparent/TransparentBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Proxy } from '../../_Proxy.sol'; 6 | import { _BeaconProxy } from '../_BeaconProxy.sol'; 7 | import { BeaconProxy } from '../BeaconProxy.sol'; 8 | import { _TransparentBeaconProxy } from './_TransparentBeaconProxy.sol'; 9 | import { ITransparentBeaconProxy } from './ITransparentBeaconProxy.sol'; 10 | 11 | abstract contract TransparentBeaconProxy is 12 | ITransparentBeaconProxy, 13 | _TransparentBeaconProxy, 14 | BeaconProxy 15 | { 16 | function _getImplementation() 17 | internal 18 | view 19 | virtual 20 | override(_BeaconProxy, BeaconProxy) 21 | returns (address implementation) 22 | { 23 | implementation = super._getImplementation(); 24 | } 25 | 26 | function _fallback() 27 | internal 28 | virtual 29 | override(_Proxy, _TransparentBeaconProxy) 30 | { 31 | super._fallback(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/storage/InitializableStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library InitializableStorage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.Initializable 10 | */ 11 | struct Layout { 12 | uint8 initialized; 13 | } 14 | 15 | sslot internal constant DEFAULT_STORAGE_SLOT = 16 | sslot.wrap( 17 | keccak256( 18 | abi.encode( 19 | uint256( 20 | keccak256(bytes('solidstate.layout.Initializable')) 21 | ) - 1 22 | ) 23 | ) & ~bytes32(uint256(0xff)) 24 | ); 25 | 26 | function layout() internal pure returns (Layout storage $) { 27 | $ = layout(DEFAULT_STORAGE_SLOT); 28 | } 29 | 30 | function layout(sslot slot) internal pure returns (Layout storage $) { 31 | assembly { 32 | $.slot := slot 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/storage/ReentrancyGuardStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ReentrancyGuardStorage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.ReentrancyGuard 10 | */ 11 | struct Layout { 12 | uint256 status; 13 | } 14 | 15 | sslot internal constant DEFAULT_STORAGE_SLOT = 16 | sslot.wrap( 17 | keccak256( 18 | abi.encode( 19 | uint256( 20 | keccak256(bytes('solidstate.layout.ReentrancyGuard')) 21 | ) - 1 22 | ) 23 | ) & ~bytes32(uint256(0xff)) 24 | ); 25 | 26 | function layout() internal pure returns (Layout storage $) { 27 | $ = layout(DEFAULT_STORAGE_SLOT); 28 | } 29 | 30 | function layout(sslot slot) internal pure returns (Layout storage $) { 31 | assembly { 32 | $.slot := slot 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/token/fungible/metadata/FungibleTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC20Metadata } from '../../../interfaces/IERC20Metadata.sol'; 6 | import { _FungibleTokenMetadata } from './_FungibleTokenMetadata.sol'; 7 | import { IFungibleTokenMetadata } from './IFungibleTokenMetadata.sol'; 8 | 9 | /** 10 | * @title ERC20 metadata extensions 11 | */ 12 | abstract contract FungibleTokenMetadata is 13 | IFungibleTokenMetadata, 14 | _FungibleTokenMetadata 15 | { 16 | /** 17 | * @inheritdoc IERC20Metadata 18 | */ 19 | function name() external view returns (string memory) { 20 | return _name(); 21 | } 22 | 23 | /** 24 | * @inheritdoc IERC20Metadata 25 | */ 26 | function symbol() external view returns (string memory) { 27 | return _symbol(); 28 | } 29 | 30 | /** 31 | * @inheritdoc IERC20Metadata 32 | */ 33 | function decimals() external view returns (uint8) { 34 | return _decimals(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/utils/Panic.ts: -------------------------------------------------------------------------------- 1 | import { PANIC_CODES } from '@nomicfoundation/hardhat-chai-matchers/panic'; 2 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 3 | import { $Panic, $Panic__factory } from '@solidstate/typechain-types'; 4 | import { expect } from 'chai'; 5 | import { ethers } from 'hardhat'; 6 | 7 | describe('Panic', async () => { 8 | let instance: $Panic; 9 | let deployer: SignerWithAddress; 10 | 11 | beforeEach(async () => { 12 | [deployer] = await ethers.getSigners(); 13 | instance = await new $Panic__factory(deployer).deploy(); 14 | }); 15 | 16 | describe('#panic(uint256)', () => { 17 | it('reverts with panic', async () => { 18 | // generic code is not included in matcher library 19 | await expect(instance.$panic.staticCall(0)).to.be.revertedWithPanic(0); 20 | 21 | for (const code of Object.values(PANIC_CODES)) { 22 | await expect(instance.$panic.staticCall(code)).to.be.revertedWithPanic( 23 | code, 24 | ); 25 | } 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /contracts/token/fungible/snapshot/FungibleTokenSnapshot.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _FungibleTokenSnapshot } from './_FungibleTokenSnapshot.sol'; 6 | import { IFungibleTokenSnapshot } from './IFungibleTokenSnapshot.sol'; 7 | 8 | /** 9 | * @title FungibleToken base implementation with support for token balance and supply snapshots 10 | */ 11 | abstract contract FungibleTokenSnapshot is 12 | IFungibleTokenSnapshot, 13 | _FungibleTokenSnapshot 14 | { 15 | /** 16 | * @inheritdoc IFungibleTokenSnapshot 17 | */ 18 | function balanceOfAt( 19 | address account, 20 | uint256 snapshotId 21 | ) external view returns (uint256 balance) { 22 | balance = _balanceOfAt(account, snapshotId); 23 | } 24 | 25 | /** 26 | * @inheritdoc IFungibleTokenSnapshot 27 | */ 28 | function totalSupplyAt( 29 | uint256 snapshotId 30 | ) external view returns (uint256 totalSupply) { 31 | totalSupply = _totalSupplyAt(snapshotId); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/_SolidstateDiamondProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _DiamondProxyFallback } from './fallback/_DiamondProxyFallback.sol'; 6 | import { _DiamondProxyReadable } from './readable/_DiamondProxyReadable.sol'; 7 | import { _DiamondProxyWritable } from './writable/_DiamondProxyWritable.sol'; 8 | import { _DiamondProxy } from './_DiamondProxy.sol'; 9 | import { _ISolidstateDiamondProxy } from './_ISolidstateDiamondProxy.sol'; 10 | 11 | abstract contract _SolidstateDiamondProxy is 12 | _ISolidstateDiamondProxy, 13 | _DiamondProxy, 14 | _DiamondProxyFallback, 15 | _DiamondProxyReadable, 16 | _DiamondProxyWritable 17 | { 18 | /** 19 | * @inheritdoc _DiamondProxyFallback 20 | */ 21 | function _getImplementation() 22 | internal 23 | view 24 | virtual 25 | override(_DiamondProxy, _DiamondProxyFallback) 26 | returns (address implementation) 27 | { 28 | implementation = super._getImplementation(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spec/token/multi/metadata/MultiTokenMetadata.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { IMultiTokenMetadata } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | 5 | export interface MultiTokenMetadataBehaviorArgs { 6 | baseURI: string; 7 | } 8 | 9 | export function describeBehaviorOfMultiTokenMetadata( 10 | deploy: () => Promise, 11 | args: MultiTokenMetadataBehaviorArgs, 12 | skips?: string[], 13 | ) { 14 | const describe = describeFilter(skips); 15 | 16 | describe('::MultiTokenMetadata', () => { 17 | let instance: IMultiTokenMetadata; 18 | 19 | beforeEach(async () => { 20 | instance = await deploy(); 21 | }); 22 | 23 | // TODO: enable for compositions that include ERC165 24 | // describeBehaviorOfIntrospectable( 25 | // deploy, 26 | // { 27 | // interfaceIds: ['0x0e89341c'], 28 | // }, 29 | // skips, 30 | // ); 31 | 32 | describe('#uri(uint256)', () => { 33 | it('todo'); 34 | }); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/ownable/ContractSignerOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ContractSigner } from '../_ContractSigner.sol'; 6 | import { ContractSigner } from '../ContractSigner.sol'; 7 | import { _ContractSignerOwnable } from './_ContractSignerOwnable.sol'; 8 | import { IContractSignerOwnable } from './IContractSignerOwnable.sol'; 9 | 10 | /** 11 | * @title ERC1271 implementation which delegates signing authority to ERC173 contract owner 12 | */ 13 | abstract contract ContractSignerOwnable is 14 | IContractSignerOwnable, 15 | _ContractSignerOwnable, 16 | ContractSigner 17 | { 18 | /** 19 | * @inheritdoc _ContractSignerOwnable 20 | */ 21 | function _isValidSignature( 22 | bytes32 hash, 23 | bytes memory signature 24 | ) 25 | internal 26 | view 27 | virtual 28 | override(_ContractSigner, _ContractSignerOwnable) 29 | returns (bytes4 magicValue) 30 | { 31 | magicValue = super._isValidSignature(hash, signature); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Nick Barry 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC721Enumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC721Enumerable } from './_IERC721Enumerable.sol'; 6 | 7 | interface IERC721Enumerable is _IERC721Enumerable { 8 | /** 9 | * @notice get total token supply 10 | * @return total supply 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @notice get token of given owner at given internal storage index 16 | * @param owner token holder to query 17 | * @param index position in owner's token list to query 18 | * @return tokenId id of retrieved token 19 | */ 20 | function tokenOfOwnerByIndex( 21 | address owner, 22 | uint256 index 23 | ) external view returns (uint256 tokenId); 24 | 25 | /** 26 | * @notice get token at given internal storage index 27 | * @param index position in global token list to query 28 | * @return tokenId id of retrieved token 29 | */ 30 | function tokenByIndex( 31 | uint256 index 32 | ) external view returns (uint256 tokenId); 33 | } 34 | -------------------------------------------------------------------------------- /contracts/test/Bytes32Test.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { Bytes32 } from '../utils/Bytes32.sol'; 6 | 7 | contract Bytes32Test { 8 | function sanitizeAddressTest( 9 | address input 10 | ) external pure returns (bytes32 outputBytes32) { 11 | bytes32 inputBytes32; 12 | 13 | // contaminate the higher-order bits 14 | assembly { 15 | inputBytes32 := or(input, shl(160, not(1))) 16 | } 17 | 18 | address output = Bytes32.toAddress(inputBytes32); 19 | 20 | assembly { 21 | outputBytes32 := output 22 | } 23 | } 24 | 25 | function sanitizeBoolTest( 26 | bool input 27 | ) external pure returns (bytes32 outputBytes32) { 28 | bytes32 inputBytes32; 29 | 30 | // contaminate the higher-order bits 31 | assembly { 32 | inputBytes32 := or(input, shl(1, not(1))) 33 | } 34 | 35 | bool output = Bytes32.toBool(inputBytes32); 36 | 37 | assembly { 38 | outputBytes32 := output 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/metadata/NonFungibleTokenMetadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC721Metadata } from '../../../interfaces/IERC721Metadata.sol'; 6 | import { _NonFungibleTokenMetadata } from './_NonFungibleTokenMetadata.sol'; 7 | import { INonFungibleTokenMetadata } from './INonFungibleTokenMetadata.sol'; 8 | 9 | /** 10 | * @title NonFungibleToken metadata extensions 11 | */ 12 | abstract contract NonFungibleTokenMetadata is 13 | INonFungibleTokenMetadata, 14 | _NonFungibleTokenMetadata 15 | { 16 | /** 17 | * @inheritdoc IERC721Metadata 18 | */ 19 | function name() external view returns (string memory) { 20 | return _name(); 21 | } 22 | 23 | /** 24 | * @inheritdoc IERC721Metadata 25 | */ 26 | function symbol() external view returns (string memory) { 27 | return _symbol(); 28 | } 29 | 30 | /** 31 | * @inheritdoc IERC721Metadata 32 | */ 33 | function tokenURI(uint256 tokenId) external view returns (string memory) { 34 | return _tokenURI(tokenId); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/token/multi/enumerable/MultiTokenEnumerable.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfMultiTokenEnumerable } from '@solidstate/spec'; 2 | import { 3 | $MultiTokenEnumerable, 4 | $MultiTokenEnumerable__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | describe('MultiTokenEnumerable', () => { 9 | let instance: $MultiTokenEnumerable; 10 | 11 | beforeEach(async () => { 12 | const [deployer] = await ethers.getSigners(); 13 | instance = await new $MultiTokenEnumerable__factory(deployer).deploy(); 14 | }); 15 | 16 | describeBehaviorOfMultiTokenEnumerable(async () => instance, { 17 | transfer: (from, to, tokenId, amount) => 18 | instance 19 | .connect(from) 20 | .safeTransferFrom( 21 | from.address, 22 | to.address, 23 | tokenId, 24 | amount, 25 | ethers.randomBytes(0), 26 | ), 27 | mint: (recipient, tokenId, amount) => 28 | instance.$_mint(recipient, tokenId, amount, '0x'), 29 | burn: (recipient, tokenId, amount) => 30 | instance.$_burn(recipient, tokenId, amount), 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/ownable/_ContractSignerOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Ownable } from '../../../access/ownable/_Ownable.sol'; 6 | import { ECDSA } from '../../../cryptography/ECDSA.sol'; 7 | import { _ContractSigner } from '../_ContractSigner.sol'; 8 | import { _IContractSignerOwnable } from './_IContractSignerOwnable.sol'; 9 | 10 | /** 11 | * @title ContractSignerOwnable internal functions 12 | */ 13 | abstract contract _ContractSignerOwnable is 14 | _IContractSignerOwnable, 15 | _ContractSigner, 16 | _Ownable 17 | { 18 | using ECDSA for bytes32; 19 | 20 | /** 21 | * @inheritdoc _ContractSigner 22 | * @notice return whether given signature is signed by contract owner 23 | */ 24 | function _isValidSignature( 25 | bytes32 hash, 26 | bytes memory signature 27 | ) internal view virtual override returns (bytes4 magicValue) { 28 | return 29 | hash.toEthSignRecoverableHash().recover(signature) == _owner() 30 | ? MAGIC_VALUE 31 | : bytes4(0); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/utils/Panic.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | library Panic { 6 | uint256 internal constant GENERIC = 0x00; 7 | uint256 internal constant ASSERTION_ERROR = 0x01; 8 | uint256 internal constant ARITHMETIC_OVERFLOW = 0x11; 9 | uint256 internal constant DIVISION_BY_ZERO = 0x12; 10 | uint256 internal constant ENUM_CONVERSION_OUT_OF_BOUNDS = 0x21; 11 | uint256 internal constant INCORRECTLY_ENCODED_STORAGE_BYTE_ARRAY = 0x22; 12 | uint256 internal constant POP_ON_EMPTY_ARRAY = 0x31; 13 | uint256 internal constant ARRAY_ACCESS_OUT_OF_BOUNDS = 0x32; 14 | uint256 internal constant TOO_MUCH_MEMORY_ALLOCATED = 0x41; 15 | uint256 internal constant ZERO_INITIALIZED_VARIABLE = 0x51; 16 | 17 | /** 18 | * @notice revert with panic 19 | * @param code panic code 20 | */ 21 | function panic(uint256 code) internal pure { 22 | // revert with the selector for Panic(uint256) 23 | assembly ('memory-safe') { 24 | mstore(0, 0x4e487b71) 25 | mstore(32, code) 26 | revert(28, 36) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/token/fungible/extended/FungibleTokenExtended.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _FungibleTokenExtended } from './_FungibleTokenExtended.sol'; 6 | import { IFungibleTokenExtended } from './IFungibleTokenExtended.sol'; 7 | 8 | /** 9 | * @title FungibleToken safe approval extensions 10 | * @dev mitigations for transaction-ordering vulnerability (see https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729) 11 | */ 12 | abstract contract FungibleTokenExtended is 13 | IFungibleTokenExtended, 14 | _FungibleTokenExtended 15 | { 16 | /** 17 | * @inheritdoc IFungibleTokenExtended 18 | */ 19 | function increaseAllowance( 20 | address spender, 21 | uint256 amount 22 | ) external returns (bool) { 23 | return _increaseAllowance(spender, amount); 24 | } 25 | 26 | /** 27 | * @inheritdoc IFungibleTokenExtended 28 | */ 29 | function decreaseAllowance( 30 | address spender, 31 | uint256 amount 32 | ) external returns (bool) { 33 | return _decreaseAllowance(spender, amount); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/token/multi/SolidstateMultiToken.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { 3 | describeBehaviorOfMultiToken, 4 | MultiTokenBehaviorArgs, 5 | describeBehaviorOfMultiTokenEnumerable, 6 | MultiTokenEnumerableBehaviorArgs, 7 | describeBehaviorOfMultiTokenMetadata, 8 | MultiTokenMetadataBehaviorArgs, 9 | } from '@solidstate/spec'; 10 | import { ISolidstateMultiToken } from '@solidstate/typechain-types'; 11 | 12 | export interface SolidstateMultiTokenBehaviorArgs 13 | extends MultiTokenBehaviorArgs, 14 | MultiTokenEnumerableBehaviorArgs, 15 | MultiTokenMetadataBehaviorArgs {} 16 | 17 | export function describeBehaviorOfSolidstateMultiToken( 18 | deploy: () => Promise, 19 | args: SolidstateMultiTokenBehaviorArgs, 20 | skips?: string[], 21 | ) { 22 | const describe = describeFilter(skips); 23 | 24 | describe('::SolidstateMultiToken', () => { 25 | describeBehaviorOfMultiToken(deploy, args, skips); 26 | 27 | describeBehaviorOfMultiTokenEnumerable(deploy, args, skips); 28 | 29 | describeBehaviorOfMultiTokenMetadata(deploy, args, skips); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /contracts/storage/ERC2981Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ERC2981Storage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.ERC2981 10 | */ 11 | struct Layout { 12 | mapping(uint256 tokenId => uint16 royaltyBPS) royaltiesBPS; 13 | uint16 defaultRoyaltyBPS; 14 | mapping(uint256 tokenId => address royaltyReceiver) royaltyReceivers; 15 | address defaultRoyaltyReceiver; 16 | } 17 | 18 | sslot internal constant DEFAULT_STORAGE_SLOT = 19 | sslot.wrap( 20 | keccak256( 21 | abi.encode( 22 | uint256(keccak256(bytes('solidstate.layout.ERC2981'))) - 1 23 | ) 24 | ) & ~bytes32(uint256(0xff)) 25 | ); 26 | 27 | function layout() internal pure returns (Layout storage $) { 28 | $ = layout(DEFAULT_STORAGE_SLOT); 29 | } 30 | 31 | function layout(sslot slot) internal pure returns (Layout storage $) { 32 | assembly { 33 | $.slot := slot 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@solidstate/spec", 3 | "version": "1.0.0-next.2", 4 | "description": "Portable specifications for Solidstate contracts", 5 | "keywords": [ 6 | "solidity", 7 | "smart-contracts", 8 | "ethereum", 9 | "ether", 10 | "eth", 11 | "cryptocurrency", 12 | "crypto", 13 | "wow", 14 | "library", 15 | "hardhat", 16 | "buidler" 17 | ], 18 | "repository": "github:solidstate-network/solidstate-solidity", 19 | "license": "MIT", 20 | "author": "Nick Barry", 21 | "main": "./dist/index.js", 22 | "types": "./dist/index.d.ts", 23 | "files": [ 24 | "dist/" 25 | ], 26 | "scripts": { 27 | "build": "pnpm clean && tsc --build tsconfig.json", 28 | "clean": "rm -rf dist/" 29 | }, 30 | "dependencies": { 31 | "@solidstate/library": "^1.0.0-next.2" 32 | }, 33 | "peerDependencies": { 34 | "@nomicfoundation/hardhat-ethers": "^3.0.0", 35 | "@nomicfoundation/hardhat-network-helpers": "^1.0.0", 36 | "ethers": "^6.0.0", 37 | "hardhat": "^2.0.0" 38 | }, 39 | "publishConfig": { 40 | "access": "public" 41 | }, 42 | "gitHead": "edd6391ae61d9e82fe0464f179ca55b746da8806" 43 | } 44 | -------------------------------------------------------------------------------- /contracts/token/fungible/extended/IFungibleTokenExtended.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IFungibleTokenExtended } from './_IFungibleTokenExtended.sol'; 6 | 7 | /** 8 | * @title FungibleToken extended interface 9 | */ 10 | interface IFungibleTokenExtended is _IFungibleTokenExtended { 11 | /** 12 | * @notice increase spend amount granted to spender 13 | * @param spender address whose allowance to increase 14 | * @param amount quantity by which to increase allowance 15 | * @return success status (always true; otherwise function will revert) 16 | */ 17 | function increaseAllowance( 18 | address spender, 19 | uint256 amount 20 | ) external returns (bool); 21 | 22 | /** 23 | * @notice decrease spend amount granted to spender 24 | * @param spender address whose allowance to decrease 25 | * @param amount quantity by which to decrease allowance 26 | * @return success status (always true; otherwise function will revert) 27 | */ 28 | function decreaseAllowance( 29 | address spender, 30 | uint256 amount 31 | ) external returns (bool); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/storage/ERC173Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | import { duration } from '../utils/time/Duration.sol'; 7 | import { timelock } from '../utils/time/Timelock.sol'; 8 | 9 | library ERC173Storage { 10 | /** 11 | * @custom:storage-location erc7201:solidstate.layout.ERC173 12 | */ 13 | struct Layout { 14 | address owner; 15 | address nomineeOwner; 16 | timelock transferTimelock; 17 | duration transferTimelockDuration; 18 | } 19 | 20 | sslot internal constant DEFAULT_STORAGE_SLOT = 21 | sslot.wrap( 22 | keccak256( 23 | abi.encode( 24 | uint256(keccak256(bytes('solidstate.layout.ERC173'))) - 1 25 | ) 26 | ) & ~bytes32(uint256(0xff)) 27 | ); 28 | 29 | function layout() internal pure returns (Layout storage $) { 30 | $ = layout(DEFAULT_STORAGE_SLOT); 31 | } 32 | 33 | function layout(sslot slot) internal pure returns (Layout storage $) { 34 | assembly { 35 | $.slot := slot 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/test/TimestampTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { timestamp } from '../utils/time/Timestamp.sol'; 6 | 7 | contract TimestampTest { 8 | function eq( 9 | timestamp t0, 10 | timestamp t1 11 | ) external pure returns (bool status) { 12 | status = t0 == t1; 13 | } 14 | 15 | function notEq( 16 | timestamp t0, 17 | timestamp t1 18 | ) external pure returns (bool status) { 19 | status = t0 != t1; 20 | } 21 | 22 | function gt( 23 | timestamp t0, 24 | timestamp t1 25 | ) external pure returns (bool status) { 26 | status = t0 > t1; 27 | } 28 | 29 | function lt( 30 | timestamp t0, 31 | timestamp t1 32 | ) external pure returns (bool status) { 33 | status = t0 < t1; 34 | } 35 | 36 | function gte( 37 | timestamp t0, 38 | timestamp t1 39 | ) external pure returns (bool status) { 40 | status = t0 >= t1; 41 | } 42 | 43 | function lte( 44 | timestamp t0, 45 | timestamp t1 46 | ) external pure returns (bool status) { 47 | status = t0 <= t1; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /contracts/proxy/transparent/_TransparentProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Proxy } from '../_Proxy.sol'; 6 | import { _ITransparentProxy } from './_ITransparentProxy.sol'; 7 | import { ITransparentProxyWithAdminFunctions } from './ITransparentProxyWithAdminFunctions.sol'; 8 | 9 | abstract contract _TransparentProxy is _ITransparentProxy, _Proxy { 10 | /** 11 | * @inheritdoc _Proxy 12 | * @dev calls matching ITransparentProxyWithAdminFunctions are processed internally if sender is admin 13 | */ 14 | function _fallback() internal virtual override { 15 | if ( 16 | msg.sig == 17 | ITransparentProxyWithAdminFunctions.setProxyAdmin.selector && 18 | _msgSender() == _getProxyAdmin() 19 | ) return _setProxyAdmin(address(bytes20(_msgData()[16:]))); 20 | if ( 21 | msg.sig == 22 | ITransparentProxyWithAdminFunctions 23 | .setImplementation 24 | .selector && 25 | _msgSender() == _getProxyAdmin() 26 | ) return _setImplementation(address(bytes20(_msgData()[16:]))); 27 | super._fallback(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/storage/AccessControlStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { EnumerableSet } from '../data/EnumerableSet.sol'; 6 | import { sslot } from '../data/StorageSlot.sol'; 7 | 8 | library AccessControlStorage { 9 | struct RoleData { 10 | EnumerableSet.AddressSet members; 11 | bytes32 adminRole; 12 | } 13 | 14 | /** 15 | * @custom:storage-location erc7201:solidstate.layout.AccessControl 16 | */ 17 | struct Layout { 18 | mapping(bytes32 roleId => RoleData roleData) roles; 19 | } 20 | 21 | sslot internal constant DEFAULT_STORAGE_SLOT = 22 | sslot.wrap( 23 | keccak256( 24 | abi.encode( 25 | uint256( 26 | keccak256(bytes('solidstate.layout.AccessControl')) 27 | ) - 1 28 | ) 29 | ) & ~bytes32(uint256(0xff)) 30 | ); 31 | 32 | function layout() internal pure returns (Layout storage $) { 33 | $ = layout(DEFAULT_STORAGE_SLOT); 34 | } 35 | 36 | function layout(sslot slot) internal pure returns (Layout storage $) { 37 | assembly { 38 | $.slot := slot 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/proxy/diamond/writable/DiamondProxyWritable.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 2 | import { describeBehaviorOfDiamondProxyWritable } from '@solidstate/spec'; 3 | import { 4 | $DiamondProxyWritable, 5 | $DiamondProxyWritable__factory, 6 | } from '@solidstate/typechain-types'; 7 | import { ethers } from 'hardhat'; 8 | 9 | describe('DiamondProxyWritable', () => { 10 | let proxyAdmin: SignerWithAddress; 11 | let nonProxyAdmin: SignerWithAddress; 12 | let instance: $DiamondProxyWritable; 13 | 14 | before(async () => { 15 | [proxyAdmin, nonProxyAdmin] = await ethers.getSigners(); 16 | }); 17 | 18 | beforeEach(async () => { 19 | const [deployer] = await ethers.getSigners(); 20 | instance = await new $DiamondProxyWritable__factory(deployer).deploy(); 21 | 22 | await instance.$_setProxyAdmin(await deployer.getAddress()); 23 | 24 | await instance.$_setSupportsInterface('0x01ffc9a7', true); 25 | await instance.$_setSupportsInterface('0x1f931c1c', true); 26 | }); 27 | 28 | describeBehaviorOfDiamondProxyWritable(async () => instance, { 29 | getProxyAdmin: async () => proxyAdmin, 30 | getNonProxyAdmin: async () => nonProxyAdmin, 31 | immutableSelectors: [], 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/utils/Int256.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 2 | import { $Int256, $Int256__factory } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | import { ethers } from 'hardhat'; 5 | 6 | describe('Int256', async () => { 7 | let instance: $Int256; 8 | let deployer: SignerWithAddress; 9 | 10 | beforeEach(async () => { 11 | [deployer] = await ethers.getSigners(); 12 | instance = await new $Int256__factory(deployer).deploy(); 13 | }); 14 | 15 | describe('#toBytes32(int256)', () => { 16 | it('returns a bytes32 representation of int256', async () => { 17 | expect(await instance.$toBytes32.staticCall(0n)).to.eq(ethers.ZeroHash); 18 | 19 | expect(await instance.$toBytes32.staticCall(-1n)).to.eq( 20 | '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 21 | ); 22 | 23 | expect(await instance.$toBytes32.staticCall(ethers.MinInt256)).to.eq( 24 | '0x8000000000000000000000000000000000000000000000000000000000000000', 25 | ); 26 | 27 | expect(await instance.$toBytes32.staticCall(ethers.MaxInt256)).to.eq( 28 | '0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 29 | ); 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /contracts/access/reentrancy_guard/TransientReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _ReentrancyGuard } from './_ReentrancyGuard.sol'; 6 | import { _TransientReentrancyGuard } from './_TransientReentrancyGuard.sol'; 7 | import { ITransientReentrancyGuard } from './ITransientReentrancyGuard.sol'; 8 | import { ReentrancyGuard } from './ReentrancyGuard.sol'; 9 | 10 | abstract contract TransientReentrancyGuard is 11 | ITransientReentrancyGuard, 12 | _TransientReentrancyGuard, 13 | ReentrancyGuard 14 | { 15 | function _isReentrancyGuardLocked() 16 | internal 17 | view 18 | virtual 19 | override(_ReentrancyGuard, _TransientReentrancyGuard) 20 | returns (bool status) 21 | { 22 | status = super._isReentrancyGuardLocked(); 23 | } 24 | 25 | function _lockReentrancyGuard() 26 | internal 27 | virtual 28 | override(_ReentrancyGuard, _TransientReentrancyGuard) 29 | { 30 | super._lockReentrancyGuard(); 31 | } 32 | 33 | function _unlockReentrancyGuard() 34 | internal 35 | virtual 36 | override(_ReentrancyGuard, _TransientReentrancyGuard) 37 | { 38 | super._unlockReentrancyGuard(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/beacon/_Beacon.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Ownable } from '../access/ownable/_Ownable.sol'; 6 | import { BeaconStorage } from '../storage/BeaconStorage.sol'; 7 | import { _IBeacon } from './_IBeacon.sol'; 8 | 9 | abstract contract _Beacon is _IBeacon, _Ownable { 10 | /** 11 | * @notice query the address of the implementation that should be used by BeaconProxy instances 12 | * @return implementation address of the implementation contract 13 | */ 14 | function _implementation() 15 | internal 16 | view 17 | virtual 18 | returns (address implementation) 19 | { 20 | implementation = BeaconStorage 21 | .layout(BeaconStorage.DEFAULT_STORAGE_SLOT) 22 | .implementation; 23 | } 24 | 25 | /** 26 | * @notice set the address of the implementation that should be used by BeaconProxy instances 27 | * @param implementation address of the implementation contract 28 | */ 29 | function _setImplementation( 30 | address implementation 31 | ) internal virtual onlyOwner { 32 | BeaconStorage 33 | .layout(BeaconStorage.DEFAULT_STORAGE_SLOT) 34 | .implementation = implementation; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/token/multi/SolidstateMultiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { MultiTokenEnumerable } from './enumerable/MultiTokenEnumerable.sol'; 6 | import { MultiTokenMetadata } from './metadata/MultiTokenMetadata.sol'; 7 | import { _MultiToken } from './_MultiToken.sol'; 8 | import { _SolidstateMultiToken } from './_SolidstateMultiToken.sol'; 9 | import { ISolidstateMultiToken } from './ISolidstateMultiToken.sol'; 10 | import { MultiToken } from './MultiToken.sol'; 11 | 12 | /** 13 | * @title Solidstate MultiToken implementation 14 | */ 15 | abstract contract SolidstateMultiToken is 16 | ISolidstateMultiToken, 17 | _SolidstateMultiToken, 18 | MultiToken, 19 | MultiTokenEnumerable, 20 | MultiTokenMetadata 21 | { 22 | /** 23 | * @inheritdoc MultiTokenEnumerable 24 | */ 25 | function _beforeTokenTransfer( 26 | address operator, 27 | address from, 28 | address to, 29 | uint256[] memory ids, 30 | uint256[] memory amounts, 31 | bytes memory data 32 | ) 33 | internal 34 | virtual 35 | override(_SolidstateMultiToken, _MultiToken, MultiTokenEnumerable) 36 | { 37 | super._beforeTokenTransfer(operator, from, to, ids, amounts, data); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/pragma.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import hre from 'hardhat'; 3 | import { 4 | TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS, 5 | TASK_COMPILE_SOLIDITY_GET_SOURCE_NAMES, 6 | TASK_COMPILE_SOLIDITY_GET_DEPENDENCY_GRAPH, 7 | } from 'hardhat/builtin-tasks/task-names'; 8 | 9 | describe('Pragma statements', () => { 10 | it('are consistent across all files', async () => { 11 | const sourcePaths = await hre.run(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS); 12 | const sourceNames = await hre.run(TASK_COMPILE_SOLIDITY_GET_SOURCE_NAMES, { 13 | sourcePaths, 14 | }); 15 | const graph = await hre.run(TASK_COMPILE_SOLIDITY_GET_DEPENDENCY_GRAPH, { 16 | sourceNames, 17 | }); 18 | const files = graph.getResolvedFiles(); 19 | 20 | const versions = new Set(); 21 | 22 | for (const file of files) { 23 | if (file.content.versionPragmas.length === 0) { 24 | throw new Error( 25 | `Missing pragma statement for file: ${file.sourceName}`, 26 | ); 27 | } 28 | 29 | for (const version of file.content.versionPragmas) { 30 | versions.add(version); 31 | } 32 | } 33 | 34 | expect(versions.size).to.equal( 35 | 1, 36 | `Multiple version pragmas in use: ${Array.from(versions).join(', ')}`, 37 | ); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /contracts/storage/ERC2535Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ERC2535Storage { 8 | /** 9 | * @custom:storage-location erc7201:solidstate.layout.ERC2535 10 | */ 11 | struct Layout { 12 | // function selector => (facet address, selector slug position) 13 | mapping(bytes4 selector => bytes32 selectorInfo) selectorInfo; 14 | // total number of selectors registered 15 | uint16 selectorCount; 16 | // array of 32-byte slugs with 8 selectors each 17 | mapping(uint256 index => bytes32 selectorSlug) selectorSlugs; 18 | address fallbackAddress; 19 | } 20 | 21 | sslot internal constant DEFAULT_STORAGE_SLOT = 22 | sslot.wrap( 23 | keccak256( 24 | abi.encode( 25 | uint256(keccak256(bytes('solidstate.layout.ERC2535'))) - 1 26 | ) 27 | ) & ~bytes32(uint256(0xff)) 28 | ); 29 | 30 | function layout() internal pure returns (Layout storage $) { 31 | $ = layout(DEFAULT_STORAGE_SLOT); 32 | } 33 | 34 | function layout(sslot slot) internal pure returns (Layout storage $) { 35 | assembly { 36 | $.slot := slot 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/token/multi/SolidstateMultiToken.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfSolidstateMultiToken } from '@solidstate/spec'; 2 | import { 3 | $SolidstateMultiToken, 4 | $SolidstateMultiToken__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | const baseURI = 'MultiTokenMetadata.baseURI'; 9 | 10 | describe('SolidstateMultiToken', () => { 11 | let instance: $SolidstateMultiToken; 12 | 13 | beforeEach(async () => { 14 | const [deployer] = await ethers.getSigners(); 15 | instance = await new $SolidstateMultiToken__factory(deployer).deploy(); 16 | 17 | await instance.$_setSupportsInterface('0x01ffc9a7', true); 18 | await instance.$_setSupportsInterface('0xd9b67a26', true); 19 | }); 20 | 21 | describeBehaviorOfSolidstateMultiToken(async () => instance, { 22 | transfer: (from, to, tokenId, amount) => 23 | instance 24 | .connect(from) 25 | .safeTransferFrom( 26 | from.address, 27 | to.address, 28 | tokenId, 29 | amount, 30 | ethers.randomBytes(0), 31 | ), 32 | mint: (recipient, tokenId, amount) => 33 | instance.$_mint(recipient, tokenId, amount, '0x'), 34 | burn: (recipient, tokenId, amount) => 35 | instance.$_burn(recipient, tokenId, amount), 36 | baseURI, 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /contracts/test/DurationTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { duration } from '../utils/time/Duration.sol'; 6 | 7 | contract DurationTest { 8 | function eq(duration d0, duration d1) external pure returns (bool status) { 9 | status = d0 == d1; 10 | } 11 | 12 | function notEq( 13 | duration d0, 14 | duration d1 15 | ) external pure returns (bool status) { 16 | status = d0 != d1; 17 | } 18 | 19 | function gt(duration d0, duration d1) external pure returns (bool status) { 20 | status = d0 > d1; 21 | } 22 | 23 | function lt(duration d0, duration d1) external pure returns (bool status) { 24 | status = d0 < d1; 25 | } 26 | 27 | function gte(duration d0, duration d1) external pure returns (bool status) { 28 | status = d0 >= d1; 29 | } 30 | 31 | function lte(duration d0, duration d1) external pure returns (bool status) { 32 | status = d0 <= d1; 33 | } 34 | 35 | function add( 36 | duration d0, 37 | duration d1 38 | ) external pure returns (duration result) { 39 | result = d0 + d1; 40 | } 41 | 42 | function sub( 43 | duration d0, 44 | duration d1 45 | ) external pure returns (duration result) { 46 | result = d0 - d1; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/transparent/_TransparentBeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Proxy } from '../../_Proxy.sol'; 6 | import { _BeaconProxy } from '../_BeaconProxy.sol'; 7 | import { _ITransparentBeaconProxy } from './_ITransparentBeaconProxy.sol'; 8 | import { ITransparentBeaconProxyWithAdminFunctions } from './ITransparentBeaconProxyWithAdminFunctions.sol'; 9 | 10 | abstract contract _TransparentBeaconProxy is 11 | _ITransparentBeaconProxy, 12 | _BeaconProxy 13 | { 14 | /** 15 | * @inheritdoc _Proxy 16 | * @dev calls matching ITransparentBeaconProxyWithAdminFunctions are processed internally if sender is admin 17 | */ 18 | function _fallback() internal virtual override { 19 | if ( 20 | msg.sig == 21 | ITransparentBeaconProxyWithAdminFunctions 22 | .setProxyAdmin 23 | .selector && 24 | _msgSender() == _getProxyAdmin() 25 | ) return _setProxyAdmin(address(bytes20(_msgData()[16:]))); 26 | if ( 27 | msg.sig == 28 | ITransparentBeaconProxyWithAdminFunctions.setBeacon.selector && 29 | _msgSender() == _getProxyAdmin() 30 | ) return _setBeacon(address(bytes20(_msgData()[16:]))); 31 | super._fallback(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/token/non_fungible/SolidstateNonFungibleToken.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfSolidstateNonFungibleToken } from '@solidstate/spec'; 2 | import { 3 | $SolidstateNonFungibleToken, 4 | $SolidstateNonFungibleToken__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | const name = 'NonFungibleTokenMetadata.name'; 9 | const symbol = 'NonFungibleTokenMetadata.symbol'; 10 | const baseURI = 'NonFungibleTokenMetadata.baseURI'; 11 | 12 | describe('SolidstateNonFungibleToken', () => { 13 | let instance: $SolidstateNonFungibleToken; 14 | 15 | beforeEach(async () => { 16 | const [deployer] = await ethers.getSigners(); 17 | instance = await new $SolidstateNonFungibleToken__factory( 18 | deployer, 19 | ).deploy(); 20 | 21 | await instance.$_setName(name); 22 | await instance.$_setSymbol(symbol); 23 | await instance.$_setBaseURI(baseURI); 24 | 25 | await instance.$_setSupportsInterface('0x01ffc9a7', true); 26 | await instance.$_setSupportsInterface('0x80ac58cd', true); 27 | }); 28 | 29 | describeBehaviorOfSolidstateNonFungibleToken(async () => instance, { 30 | supply: 0n, 31 | mint: async (recipient, tokenId) => instance.$_mint(recipient, tokenId), 32 | burn: async (tokenId) => instance.$_burn(tokenId), 33 | name, 34 | symbol, 35 | baseURI, 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/token/fungible/SolidstateFungibleToken.ts: -------------------------------------------------------------------------------- 1 | import { describeBehaviorOfSolidstateFungibleToken } from '@solidstate/spec'; 2 | import { 3 | $SolidstateFungibleToken, 4 | $SolidstateFungibleToken__factory, 5 | } from '@solidstate/typechain-types'; 6 | import { ethers } from 'hardhat'; 7 | 8 | const name = 'FungibleTokenMetadata.name'; 9 | const symbol = 'FungibleTokenMetadata.symbol'; 10 | const decimals = 18n; 11 | const supply = ethers.parseEther('1'); 12 | 13 | describe('SolidstateFungibleToken', () => { 14 | let instance: $SolidstateFungibleToken; 15 | 16 | beforeEach(async () => { 17 | const [deployer] = await ethers.getSigners(); 18 | instance = await new $SolidstateFungibleToken__factory(deployer).deploy(); 19 | 20 | await instance.$_setName(name); 21 | await instance.$_setSymbol(symbol); 22 | await instance.$_setDecimals(decimals); 23 | 24 | await instance.$_mint(await deployer.getAddress(), supply); 25 | }); 26 | 27 | describeBehaviorOfSolidstateFungibleToken(async () => instance, { 28 | mint: async (recipient, amount) => instance.$_mint(recipient, amount), 29 | burn: async (recipient, amount) => instance.$_burn(recipient, amount), 30 | allowance: (holder, spender) => 31 | instance.allowance.staticCall(holder, spender), 32 | name, 33 | symbol, 34 | decimals, 35 | supply, 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/fallback/DiamondProxyFallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { DiamondProxy } from '../DiamondProxy.sol'; 6 | import { _DiamondProxyFallback } from './_DiamondProxyFallback.sol'; 7 | import { IDiamondProxyFallback } from './IDiamondProxyFallback.sol'; 8 | 9 | /** 10 | * @title Fallback feature for EIP-2535 "Diamond" proxy 11 | */ 12 | abstract contract DiamondProxyFallback is 13 | IDiamondProxyFallback, 14 | _DiamondProxyFallback, 15 | DiamondProxy 16 | { 17 | /** 18 | * @inheritdoc IDiamondProxyFallback 19 | */ 20 | function getFallbackAddress() 21 | external 22 | view 23 | returns (address fallbackAddress) 24 | { 25 | fallbackAddress = _getFallbackAddress(); 26 | } 27 | 28 | /** 29 | * @inheritdoc IDiamondProxyFallback 30 | */ 31 | function setFallbackAddress(address fallbackAddress) external { 32 | _setFallbackAddressExternal(fallbackAddress); 33 | } 34 | 35 | /** 36 | * @inheritdoc _DiamondProxyFallback 37 | */ 38 | function _getImplementation() 39 | internal 40 | view 41 | virtual 42 | override(DiamondProxy, _DiamondProxyFallback) 43 | returns (address implementation) 44 | { 45 | implementation = super._getImplementation(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/signature/contract_signer/_ContractSigner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC1271 } from '../../interfaces/IERC1271.sol'; 6 | import { ERC1271Storage } from '../../storage/ERC1271Storage.sol'; 7 | import { _IContractSigner } from './_IContractSigner.sol'; 8 | 9 | /** 10 | * @title ContractSigner internal functions 11 | */ 12 | abstract contract _ContractSigner is _IContractSigner { 13 | bytes4 internal constant MAGIC_VALUE = IERC1271.isValidSignature.selector; 14 | 15 | /** 16 | * @notice return whether given signature is valid 17 | * @param hash hashed data 18 | * @param signature signed hash 19 | * @return magicValue ERC1271 magic value or null bytes 20 | */ 21 | function _isValidSignature( 22 | bytes32 hash, 23 | bytes memory signature 24 | ) internal view virtual returns (bytes4 magicValue) { 25 | signature; 26 | 27 | return 28 | ERC1271Storage.layout(ERC1271Storage.DEFAULT_STORAGE_SLOT).hashes[ 29 | hash 30 | ] 31 | ? MAGIC_VALUE 32 | : bytes4(0); 33 | } 34 | 35 | function _setValidSignature(bytes32 hash, bool status) internal virtual { 36 | ERC1271Storage.layout(ERC1271Storage.DEFAULT_STORAGE_SLOT).hashes[ 37 | hash 38 | ] = status; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /spec/token/fungible/SolidstateFungibleToken.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { 3 | describeBehaviorOfFungibleToken, 4 | FungibleTokenBehaviorArgs, 5 | describeBehaviorOfFungibleTokenExtended, 6 | FungibleTokenExtendedBehaviorArgs, 7 | describeBehaviorOfFungibleTokenMetadata, 8 | FungibleTokenMetadataBehaviorArgs, 9 | describeBehaviorOfFungibleTokenPermit, 10 | FungibleTokenPermitBehaviorArgs, 11 | } from '@solidstate/spec'; 12 | import { ISolidstateFungibleToken } from '@solidstate/typechain-types'; 13 | 14 | export interface SolidstateFungibleTokenBehaviorArgs 15 | extends FungibleTokenBehaviorArgs, 16 | FungibleTokenExtendedBehaviorArgs, 17 | FungibleTokenMetadataBehaviorArgs, 18 | FungibleTokenPermitBehaviorArgs {} 19 | 20 | export function describeBehaviorOfSolidstateFungibleToken( 21 | deploy: () => Promise, 22 | args: SolidstateFungibleTokenBehaviorArgs, 23 | skips?: string[], 24 | ) { 25 | const describe = describeFilter(skips); 26 | 27 | describe('::SolidstateFungibleToken', () => { 28 | describeBehaviorOfFungibleToken(deploy, args, skips); 29 | 30 | describeBehaviorOfFungibleTokenExtended(deploy, args, skips); 31 | 32 | describeBehaviorOfFungibleTokenMetadata(deploy, args, skips); 33 | 34 | describeBehaviorOfFungibleTokenPermit(deploy, args, skips); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /spec/token/fungible/metadata/FungibleTokenMetadata.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { IFungibleTokenMetadata } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | 5 | export interface FungibleTokenMetadataBehaviorArgs { 6 | name: string; 7 | symbol: string; 8 | decimals: bigint; 9 | } 10 | 11 | export function describeBehaviorOfFungibleTokenMetadata( 12 | deploy: () => Promise, 13 | args: FungibleTokenMetadataBehaviorArgs, 14 | skips?: string[], 15 | ) { 16 | const describe = describeFilter(skips); 17 | 18 | describe('::FungibleTokenMetadata', () => { 19 | let instance: IFungibleTokenMetadata; 20 | 21 | beforeEach(async () => { 22 | instance = await deploy(); 23 | }); 24 | 25 | describe('#name()', () => { 26 | it('returns token name', async () => { 27 | expect(await instance.name.staticCall()).to.equal(args.name); 28 | }); 29 | }); 30 | 31 | describe('#symbol()', () => { 32 | it('returns token symbol', async () => { 33 | expect(await instance.symbol.staticCall()).to.equal(args.symbol); 34 | }); 35 | }); 36 | 37 | describe('#decimals()', () => { 38 | it('returns token decimals', async () => { 39 | expect(await instance.decimals.staticCall()).to.equal(args.decimals); 40 | }); 41 | }); 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /contracts/meta/_Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IContext } from './_IContext.sol'; 6 | 7 | /** 8 | * @title Utility contract for supporting alternative authorization schemes 9 | */ 10 | abstract contract _Context is _IContext { 11 | /** 12 | * @notice return the message sender 13 | * @dev if no Context extension is in use, msg.sender is returned as-is 14 | * @return msgSender account contextualized as message sender 15 | */ 16 | function _msgSender() internal view virtual returns (address msgSender) { 17 | msgSender = msg.sender; 18 | } 19 | 20 | /** 21 | * @notice return the message data 22 | * @dev if no Context extension is in use, msg.data is returned as-is 23 | * @return msgData message data with suffix removed, if applicable 24 | */ 25 | function _msgData() internal view virtual returns (bytes calldata msgData) { 26 | msgData = msg.data; 27 | } 28 | 29 | /** 30 | * @notice return the bytes length of the calldata context suffix 31 | * @dev if no Context extension is in use, suffix length is 0 32 | * @return length length of calldata context suffix 33 | */ 34 | function _calldataSuffixLength() 35 | internal 36 | view 37 | virtual 38 | returns (uint256 length) 39 | { 40 | length = 0; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /spec/signature/contract_signer/ContractSigner.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { IContractSigner } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | 5 | export interface ContractSignerBehaviorArgs { 6 | getValidParams: () => Promise<[Uint8Array, Uint8Array]>; 7 | getInvalidParams: () => Promise<[Uint8Array, Uint8Array]>; 8 | } 9 | 10 | export function describeBehaviorOfContractSigner( 11 | deploy: () => Promise, 12 | args: ContractSignerBehaviorArgs, 13 | skips?: string[], 14 | ) { 15 | const describe = describeFilter(skips); 16 | 17 | describe('::ContractSigner', () => { 18 | let instance: IContractSigner; 19 | 20 | beforeEach(async () => { 21 | instance = await deploy(); 22 | }); 23 | 24 | describe('#isValidSignature(bytes32,bytes)', () => { 25 | it('returns 0x1626ba7e for valid signature', async () => { 26 | expect( 27 | await instance.isValidSignature.staticCall( 28 | ...(await args.getValidParams()), 29 | ), 30 | ).to.equal('0x1626ba7e'); 31 | }); 32 | 33 | it('returns 0x00000000 for invalid signature', async () => { 34 | expect( 35 | await instance.isValidSignature.staticCall( 36 | ...(await args.getInvalidParams()), 37 | ), 38 | ).to.equal('0x00000000'); 39 | }); 40 | }); 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /contracts/access/initializable/_Initializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { InitializableStorage } from '../../storage/InitializableStorage.sol'; 6 | import { Address } from '../../utils/Address.sol'; 7 | import { _IInitializable } from './_IInitializable.sol'; 8 | 9 | abstract contract _Initializable is _IInitializable { 10 | using Address for address; 11 | using InitializableStorage for InitializableStorage.Layout; 12 | 13 | modifier initializer() { 14 | _setInitializedVersion(1); 15 | _; 16 | } 17 | 18 | modifier reinitializer(uint8 version) { 19 | _setInitializedVersion(version); 20 | _; 21 | } 22 | 23 | function _setInitializedVersion(uint8 version) internal virtual { 24 | InitializableStorage.Layout storage $ = InitializableStorage.layout( 25 | InitializableStorage.DEFAULT_STORAGE_SLOT 26 | ); 27 | 28 | if ($.initialized >= version) 29 | revert Initializable__AlreadyInitialized(); 30 | 31 | $.initialized = version; 32 | emit Initialized(version); 33 | } 34 | 35 | function _getInitializedVersion() 36 | internal 37 | view 38 | virtual 39 | returns (uint8 version) 40 | { 41 | version = InitializableStorage 42 | .layout(InitializableStorage.DEFAULT_STORAGE_SLOT) 43 | .initialized; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/token/fungible/permit/FungibleTokenPermit.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; 2 | import { describeBehaviorOfFungibleTokenPermit } from '@solidstate/spec'; 3 | import { 4 | $FungibleTokenPermit, 5 | $FungibleTokenPermit__factory, 6 | } from '@solidstate/typechain-types'; 7 | import { expect } from 'chai'; 8 | import { ethers } from 'hardhat'; 9 | 10 | describe('FungibleTokenPermit', () => { 11 | const name = 'FungibleTokenMetadata.name'; 12 | 13 | let deployer: SignerWithAddress; 14 | let instance: $FungibleTokenPermit; 15 | 16 | before(async () => { 17 | [deployer] = await ethers.getSigners(); 18 | }); 19 | 20 | beforeEach(async () => { 21 | instance = await new $FungibleTokenPermit__factory(deployer).deploy(); 22 | 23 | await instance.$_setName(name); 24 | }); 25 | 26 | describeBehaviorOfFungibleTokenPermit(async () => instance, { 27 | allowance: (holder, spender) => 28 | instance.$_allowance.staticCall(holder, spender), 29 | }); 30 | 31 | describe('#_DOMAIN_SEPARATOR()', () => { 32 | it('changes if token name is changed', async () => { 33 | const oldDomainSeparator = await instance.DOMAIN_SEPARATOR.staticCall(); 34 | await instance.$_setName(`new ${name}`); 35 | const newDomainSeparator = await instance.DOMAIN_SEPARATOR.staticCall(); 36 | expect(newDomainSeparator).not.to.eq(oldDomainSeparator); 37 | }); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC2612.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2612 } from './_IERC2612.sol'; 6 | 7 | /** 8 | * @title ERC2612 interface 9 | * @dev see https://eips.ethereum.org/EIPS/eip-2612. 10 | */ 11 | interface IERC2612 is _IERC2612 { 12 | /** 13 | * @notice return the EIP-712 domain separator unique to contract and chain 14 | * @return domainSeparator domain separator 15 | */ 16 | function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator); 17 | 18 | /** 19 | * @notice get the current ERC2612 nonce for the given address 20 | * @return current nonce 21 | */ 22 | function nonces(address owner) external view returns (uint256); 23 | 24 | /** 25 | * @notice approve spender to transfer tokens held by owner via signature 26 | * @dev this function may be vulnerable to approval replay attacks 27 | * @param owner holder of tokens and signer of permit 28 | * @param spender beneficiary of approval 29 | * @param amount quantity of tokens to approve 30 | * @param v secp256k1 'v' value 31 | * @param r secp256k1 'r' value 32 | * @param s secp256k1 's' value 33 | */ 34 | function permit( 35 | address owner, 36 | address spender, 37 | uint256 amount, 38 | uint256 deadline, 39 | uint8 v, 40 | bytes32 r, 41 | bytes32 s 42 | ) external; 43 | } 44 | -------------------------------------------------------------------------------- /contracts/token/multi/enumerable/IMultiTokenEnumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IMultiToken } from '../IMultiToken.sol'; 6 | import { _IMultiTokenEnumerable } from './_IMultiTokenEnumerable.sol'; 7 | 8 | /** 9 | * @title MultiToken enumerable and aggregate function interface 10 | */ 11 | interface IMultiTokenEnumerable is _IMultiTokenEnumerable, IMultiToken { 12 | /** 13 | * @notice query total minted supply of given token 14 | * @param id token id to query 15 | * @return token supply 16 | */ 17 | function totalSupply(uint256 id) external view returns (uint256); 18 | 19 | /** 20 | * @notice query total number of holders for given token 21 | * @param id token id to query 22 | * @return quantity of holders 23 | */ 24 | function totalHolders(uint256 id) external view returns (uint256); 25 | 26 | /** 27 | * @notice query holders of given token 28 | * @param id token id to query 29 | * @return list of holder addresses 30 | */ 31 | function accountsByToken( 32 | uint256 id 33 | ) external view returns (address[] memory); 34 | 35 | /** 36 | * @notice query tokens held by given address 37 | * @param account address to query 38 | * @return list of token ids 39 | */ 40 | function tokensByAccount( 41 | address account 42 | ) external view returns (uint256[] memory); 43 | } 44 | -------------------------------------------------------------------------------- /contracts/storage/ERC721Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { EnumerableMap } from '../data/EnumerableMap.sol'; 6 | import { EnumerableSet } from '../data/EnumerableSet.sol'; 7 | import { sslot } from '../data/StorageSlot.sol'; 8 | 9 | library ERC721Storage { 10 | /** 11 | * @custom:storage-location erc7201:solidstate.layout.ERC721 12 | */ 13 | struct Layout { 14 | EnumerableMap.UintToAddressMap tokenOwners; 15 | mapping(address account => EnumerableSet.UintSet tokenIds) holderTokens; 16 | mapping(uint256 tokenId => address account) tokenApprovals; 17 | mapping(address holder => mapping(address operator => bool approvalStatus)) operatorApprovals; 18 | string name; 19 | string symbol; 20 | string baseURI; 21 | mapping(uint256 tokenId => string tokenURI) tokenURIs; 22 | } 23 | 24 | sslot internal constant DEFAULT_STORAGE_SLOT = 25 | sslot.wrap( 26 | keccak256( 27 | abi.encode( 28 | uint256(keccak256(bytes('solidstate.layout.ERC721'))) - 1 29 | ) 30 | ) & ~bytes32(uint256(0xff)) 31 | ); 32 | 33 | function layout() internal pure returns (Layout storage $) { 34 | $ = layout(DEFAULT_STORAGE_SLOT); 35 | } 36 | 37 | function layout(sslot slot) internal pure returns (Layout storage $) { 38 | assembly { 39 | $.slot := slot 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/introspection/_Introspectable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { ERC165Storage } from '../storage/ERC165Storage.sol'; 6 | import { _IIntrospectable } from './_IIntrospectable.sol'; 7 | 8 | /** 9 | * @title ERC165 implementation 10 | */ 11 | abstract contract _Introspectable is _IIntrospectable { 12 | /** 13 | * @notice indicates whether an interface is already supported based on the interfaceId 14 | * @param interfaceId id of interface to check 15 | * @return bool indicating whether interface is supported 16 | */ 17 | function _supportsInterface( 18 | bytes4 interfaceId 19 | ) internal view virtual returns (bool) { 20 | return 21 | ERC165Storage 22 | .layout(ERC165Storage.DEFAULT_STORAGE_SLOT) 23 | .supportedInterfaces[interfaceId]; 24 | } 25 | 26 | /** 27 | * @notice sets status of interface support 28 | * @param interfaceId id of interface to set status for 29 | * @param status boolean indicating whether interface will be set as supported 30 | */ 31 | function _setSupportsInterface( 32 | bytes4 interfaceId, 33 | bool status 34 | ) internal virtual { 35 | if (interfaceId == 0xffffffff) 36 | revert Introspectable__InvalidInterfaceId(); 37 | ERC165Storage 38 | .layout(ERC165Storage.DEFAULT_STORAGE_SLOT) 39 | .supportedInterfaces[interfaceId] = status; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/proxy/beacon/_BeaconProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IBeacon } from '../../beacon/IBeacon.sol'; 6 | import { ERC1967Storage } from '../../storage/ERC1967Storage.sol'; 7 | import { Address } from '../../utils/Address.sol'; 8 | import { Bytes32 } from '../../utils/Bytes32.sol'; 9 | import { _Proxy } from '../_Proxy.sol'; 10 | import { _IBeaconProxy } from './_IBeaconProxy.sol'; 11 | 12 | abstract contract _BeaconProxy is _IBeaconProxy, _Proxy { 13 | using Address for address; 14 | using Bytes32 for bytes32; 15 | 16 | /** 17 | * @inheritdoc _Proxy 18 | */ 19 | function _getImplementation() 20 | internal 21 | view 22 | virtual 23 | override 24 | returns (address implementation) 25 | { 26 | implementation = IBeacon(_getBeacon()).implementation(); 27 | } 28 | 29 | /** 30 | * @notice query the EIP-1967 beacon address 31 | * @return beacon beacon contract address 32 | */ 33 | function _getBeacon() internal view virtual returns (address beacon) { 34 | beacon = ERC1967Storage.BEACON_STORAGE_SLOT.read().toAddress(); 35 | } 36 | 37 | /** 38 | * @notice update the EIP-1967 beacon address 39 | * @param beacon beacon contract address 40 | */ 41 | function _setBeacon(address beacon) internal virtual { 42 | ERC1967Storage.BEACON_STORAGE_SLOT.write(beacon.toBytes32()); 43 | 44 | emit BeaconUpgraded(beacon); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/storage/ERC1155Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { EnumerableSet } from '../data/EnumerableSet.sol'; 6 | import { sslot } from '../data/StorageSlot.sol'; 7 | 8 | library ERC1155Storage { 9 | /** 10 | * @custom:storage-location erc7201:solidstate.layout.ERC1155 11 | */ 12 | struct Layout { 13 | mapping(uint256 tokenId => mapping(address account => uint256 balance)) balances; 14 | mapping(address holder => mapping(address operator => bool approvalStatus)) operatorApprovals; 15 | string baseURI; 16 | mapping(uint256 tokenId => string tokenURI) tokenURIs; 17 | mapping(uint256 tokenId => uint256 supply) totalSupply; 18 | mapping(uint256 tokenId => EnumerableSet.AddressSet holders) accountsByToken; 19 | mapping(address account => EnumerableSet.UintSet tokenIds) tokensByAccount; 20 | } 21 | 22 | sslot internal constant DEFAULT_STORAGE_SLOT = 23 | sslot.wrap( 24 | keccak256( 25 | abi.encode( 26 | uint256(keccak256(bytes('solidstate.layout.ERC1155'))) - 1 27 | ) 28 | ) & ~bytes32(uint256(0xff)) 29 | ); 30 | 31 | function layout() internal pure returns (Layout storage $) { 32 | $ = layout(DEFAULT_STORAGE_SLOT); 33 | } 34 | 35 | function layout(sslot slot) internal pure returns (Layout storage $) { 36 | assembly { 37 | $.slot := slot 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/cryptography/MerkleProof.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | /** 6 | * @title Merkle tree verification utility 7 | * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) 8 | */ 9 | library MerkleProof { 10 | /** 11 | * @notice verify whether given leaf is contained within Merkle tree defined by given root 12 | * @param proof proof that Merkle tree contains given leaf 13 | * @param root Merkle tree root 14 | * @param leaf element whose presence in Merkle tree to prove 15 | * @return whether leaf is proven to be contained within Merkle tree defined by root 16 | */ 17 | function verify( 18 | bytes32[] memory proof, 19 | bytes32 root, 20 | bytes32 leaf 21 | ) internal pure returns (bool) { 22 | unchecked { 23 | bytes32 computedHash = leaf; 24 | 25 | for (uint256 i = 0; i < proof.length; i++) { 26 | bytes32 proofElement = proof[i]; 27 | 28 | if (computedHash <= proofElement) { 29 | computedHash = keccak256( 30 | abi.encodePacked(computedHash, proofElement) 31 | ); 32 | } else { 33 | computedHash = keccak256( 34 | abi.encodePacked(proofElement, computedHash) 35 | ); 36 | } 37 | } 38 | 39 | return computedHash == root; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/token/non_fungible/enumerable/NonFungibleTokenEnumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { EnumerableMap } from '../../../data/EnumerableMap.sol'; 6 | import { EnumerableSet } from '../../../data/EnumerableSet.sol'; 7 | import { IERC721Enumerable } from '../../../interfaces/IERC721Enumerable.sol'; 8 | import { NonFungibleToken } from '../NonFungibleToken.sol'; 9 | import { _NonFungibleTokenEnumerable } from './_NonFungibleTokenEnumerable.sol'; 10 | import { INonFungibleTokenEnumerable } from './INonFungibleTokenEnumerable.sol'; 11 | 12 | abstract contract NonFungibleTokenEnumerable is 13 | INonFungibleTokenEnumerable, 14 | _NonFungibleTokenEnumerable, 15 | NonFungibleToken 16 | { 17 | using EnumerableMap for EnumerableMap.UintToAddressMap; 18 | using EnumerableSet for EnumerableSet.UintSet; 19 | 20 | /** 21 | * @inheritdoc IERC721Enumerable 22 | */ 23 | function totalSupply() external view returns (uint256) { 24 | return _totalSupply(); 25 | } 26 | 27 | /** 28 | * @inheritdoc IERC721Enumerable 29 | */ 30 | function tokenOfOwnerByIndex( 31 | address owner, 32 | uint256 index 33 | ) external view returns (uint256) { 34 | return _tokenOfOwnerByIndex(owner, index); 35 | } 36 | 37 | /** 38 | * @inheritdoc IERC721Enumerable 39 | */ 40 | function tokenByIndex(uint256 index) external view returns (uint256) { 41 | return _tokenByIndex(index); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/storage/ERC1967Storage.ts: -------------------------------------------------------------------------------- 1 | import { 2 | $ERC1967Storage, 3 | $ERC1967Storage__factory, 4 | } from '@solidstate/typechain-types'; 5 | import { expect } from 'chai'; 6 | import { ethers } from 'hardhat'; 7 | 8 | describe('ERC1967Storage', () => { 9 | let instance: $ERC1967Storage; 10 | let testInstance: $ERC1967Storage; 11 | 12 | beforeEach(async () => { 13 | const [deployer] = await ethers.getSigners(); 14 | instance = await new $ERC1967Storage__factory(deployer).deploy(); 15 | testInstance = await new $ERC1967Storage__factory(deployer).deploy(); 16 | }); 17 | 18 | describe('#IMPLEMENTATION_STORAGE_SLOT', () => { 19 | it('returns EIP-1967 implementation storage slot', async () => { 20 | expect(await instance.$IMPLEMENTATION_STORAGE_SLOT.staticCall()).to.equal( 21 | '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', 22 | ); 23 | }); 24 | }); 25 | 26 | describe('#BEACON_STORAGE_SLOT', () => { 27 | it('returns EIP-1967 beacon storage slot', async () => { 28 | expect(await instance.$BEACON_STORAGE_SLOT.staticCall()).to.equal( 29 | '0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50', 30 | ); 31 | }); 32 | }); 33 | 34 | describe('#ADMIN_STORAGE_SLOT', () => { 35 | it('returns EIP-1967 admin storage slot', async () => { 36 | expect(await instance.$ADMIN_STORAGE_SLOT.staticCall()).to.equal( 37 | '0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103', 38 | ); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC1155Receiver } from './_IERC1155Receiver.sol'; 6 | import { IERC165 } from './IERC165.sol'; 7 | 8 | /** 9 | * @title ERC1155 transfer receiver interface 10 | */ 11 | interface IERC1155Receiver is _IERC1155Receiver, IERC165 { 12 | /** 13 | * @notice validate receipt of ERC1155 transfer 14 | * @param operator executor of transfer 15 | * @param from sender of tokens 16 | * @param id token ID received 17 | * @param value quantity of tokens received 18 | * @param data data payload 19 | * @return function's own selector if transfer is accepted 20 | */ 21 | function onERC1155Received( 22 | address operator, 23 | address from, 24 | uint256 id, 25 | uint256 value, 26 | bytes calldata data 27 | ) external returns (bytes4); 28 | 29 | /** 30 | * @notice validate receipt of ERC1155 batch transfer 31 | * @param operator executor of transfer 32 | * @param from sender of tokens 33 | * @param ids token IDs received 34 | * @param values quantities of tokens received 35 | * @param data data payload 36 | * @return function's own selector if transfer is accepted 37 | */ 38 | function onERC1155BatchReceived( 39 | address operator, 40 | address from, 41 | uint256[] calldata ids, 42 | uint256[] calldata values, 43 | bytes calldata data 44 | ) external returns (bytes4); 45 | } 46 | -------------------------------------------------------------------------------- /spec/token/non_fungible/metadata/NonFungibleTokenMetadata.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { INonFungibleTokenMetadata } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | 5 | export interface NonFungibleTokenMetadataBehaviorArgs { 6 | name: string; 7 | symbol: string; 8 | baseURI: string; 9 | } 10 | 11 | export function describeBehaviorOfNonFungibleTokenMetadata( 12 | deploy: () => Promise, 13 | args: NonFungibleTokenMetadataBehaviorArgs, 14 | skips?: string[], 15 | ) { 16 | const describe = describeFilter(skips); 17 | 18 | describe('::NonFungibleTokenMetadata', () => { 19 | let instance: INonFungibleTokenMetadata; 20 | 21 | beforeEach(async () => { 22 | instance = await deploy(); 23 | }); 24 | 25 | // TODO: enable for compositions that include ERC165 26 | // describeBehaviorOfIntrospectable( 27 | // deploy, 28 | // { 29 | // interfaceIds: ['0x5b5e139f'], 30 | // }, 31 | // skips, 32 | // ); 33 | 34 | describe('#name()', () => { 35 | it('returns token name', async () => { 36 | expect(await instance.name.staticCall()).to.equal(args.name); 37 | }); 38 | }); 39 | 40 | describe('#symbol()', () => { 41 | it('returns token symbol', async () => { 42 | expect(await instance.symbol.staticCall()).to.equal(args.symbol); 43 | }); 44 | }); 45 | 46 | describe('#tokenURI(uint256)', () => { 47 | it('todo'); 48 | }); 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC3156FlashLender.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC3156FlashLender } from './_IERC3156FlashLender.sol'; 6 | import { IERC3156FlashBorrower } from './IERC3156FlashBorrower.sol'; 7 | 8 | interface IERC3156FlashLender is _IERC3156FlashLender { 9 | /** 10 | * @notice The amount of currency available to be lent. 11 | * @param token The loan currency. 12 | * @return The amount of `token` that can be borrowed. 13 | */ 14 | function maxFlashLoan(address token) external view returns (uint256); 15 | 16 | /** 17 | * @notice The fee to be charged for a given loan. 18 | * @param token The loan currency. 19 | * @param amount The amount of tokens lent. 20 | * @return The amount of `token` to be charged for the loan, on top of the returned principal. 21 | */ 22 | function flashFee( 23 | address token, 24 | uint256 amount 25 | ) external view returns (uint256); 26 | 27 | /** 28 | * @notice Initiate a flash loan. 29 | * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. 30 | * @param token The loan currency. 31 | * @param amount The amount of tokens lent. 32 | * @param data Arbitrary data structure, intended to contain user-defined parameters. 33 | */ 34 | function flashLoan( 35 | IERC3156FlashBorrower receiver, 36 | address token, 37 | uint256 amount, 38 | bytes calldata data 39 | ) external returns (bool); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC2535DiamondLoupe.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _IERC2535DiamondLoupe } from './_IERC2535DiamondLoupe.sol'; 6 | import { IERC165 } from './IERC165.sol'; 7 | 8 | /** 9 | * @title ERC2535 read interface 10 | * @dev see https://eips.ethereum.org/EIPS/eip-2535 11 | */ 12 | interface IERC2535DiamondLoupe is _IERC2535DiamondLoupe, IERC165 { 13 | /** 14 | * @notice get all facets and their selectors 15 | * @return diamondFacets array of structured facet data 16 | */ 17 | function facets() external view returns (Facet[] memory diamondFacets); 18 | 19 | /** 20 | * @notice get all selectors for given facet address 21 | * @param facet address of facet to query 22 | * @return selectors array of function selectors 23 | */ 24 | function facetFunctionSelectors( 25 | address facet 26 | ) external view returns (bytes4[] memory selectors); 27 | 28 | /** 29 | * @notice get addresses of all facets used by diamond 30 | * @return addresses array of facet addresses 31 | */ 32 | function facetAddresses() 33 | external 34 | view 35 | returns (address[] memory addresses); 36 | 37 | /** 38 | * @notice get the address of the facet associated with given selector 39 | * @param selector function selector to query 40 | * @return facet facet address (zero address if not found) 41 | */ 42 | function facetAddress( 43 | bytes4 selector 44 | ) external view returns (address facet); 45 | } 46 | -------------------------------------------------------------------------------- /spec/introspection/Introspectable.behavior.ts: -------------------------------------------------------------------------------- 1 | import { describeFilter } from '@solidstate/library'; 2 | import { Introspectable } from '@solidstate/typechain-types'; 3 | import { expect } from 'chai'; 4 | 5 | export interface IntrospectableBehaviorArgs { 6 | interfaceIds: string[]; 7 | } 8 | 9 | export function describeBehaviorOfIntrospectable( 10 | deploy: () => Promise, 11 | args: IntrospectableBehaviorArgs, 12 | skips?: string[], 13 | ) { 14 | const describe = describeFilter(skips); 15 | 16 | describe('::Introspectable', () => { 17 | let instance: Introspectable; 18 | 19 | beforeEach(async () => { 20 | instance = await deploy(); 21 | }); 22 | 23 | describe('#supportsInterface(bytes4)', () => { 24 | it('returns true for ERC165 interface', async () => { 25 | expect(await instance.supportsInterface.staticCall('0x01ffc9a7')).to.be 26 | .true; 27 | }); 28 | 29 | it('returns false for unknown interface', async () => { 30 | expect(await instance.supportsInterface.staticCall('0x00000000')).to.be 31 | .false; 32 | }); 33 | 34 | it('returns false for invalid interface', async () => { 35 | expect(await instance.supportsInterface.staticCall('0xffffffff')).to.be 36 | .false; 37 | }); 38 | 39 | for (let interfaceId of args.interfaceIds) { 40 | it(`returns true for interface ${interfaceId}`, async () => { 41 | expect(await instance.supportsInterface.staticCall(interfaceId)).to.be 42 | .true; 43 | }); 44 | } 45 | }); 46 | }); 47 | } 48 | -------------------------------------------------------------------------------- /contracts/access/access_control/ownable/AccessControlOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Ownable } from '../../ownable/_Ownable.sol'; 6 | import { Ownable } from '../../ownable/Ownable.sol'; 7 | import { _AccessControl } from '../_AccessControl.sol'; 8 | import { AccessControl } from '../AccessControl.sol'; 9 | import { _AccessControlOwnable } from './_AccessControlOwnable.sol'; 10 | import { IAccessControlOwnable } from './IAccessControlOwnable.sol'; 11 | 12 | /** 13 | * @title Role-based access control system with default admin rules 14 | */ 15 | abstract contract AccessControlOwnable is 16 | IAccessControlOwnable, 17 | _AccessControlOwnable, 18 | AccessControl, 19 | Ownable 20 | { 21 | function _grantRole( 22 | bytes32 role, 23 | address account 24 | ) internal virtual override(_AccessControl, _AccessControlOwnable) { 25 | super._grantRole(role, account); 26 | } 27 | 28 | function _revokeRole( 29 | bytes32 role, 30 | address account 31 | ) internal virtual override(_AccessControl, _AccessControlOwnable) { 32 | super._revokeRole(role, account); 33 | } 34 | 35 | function _setRoleAdmin( 36 | bytes32 role, 37 | bytes32 adminRole 38 | ) internal virtual override(_AccessControl, _AccessControlOwnable) { 39 | super._setRoleAdmin(role, adminRole); 40 | } 41 | 42 | function _setOwner( 43 | address account 44 | ) internal virtual override(_Ownable, _AccessControlOwnable) { 45 | super._setOwner(account); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import './tasks/compile'; 2 | import './tasks/generate_bytes32_builder'; 3 | import './tasks/generate_eip_712'; 4 | import './tasks/organize_test_files'; 5 | import './tasks/rename_entity'; 6 | import './tasks/scaffold_contract'; 7 | import '@nomicfoundation/hardhat-chai-matchers'; 8 | import '@nomicfoundation/hardhat-ethers'; 9 | import '@solidstate/hardhat-4byte-uploader'; 10 | import '@typechain/hardhat'; 11 | import 'hardhat-abi-exporter'; 12 | import 'hardhat-contract-sizer'; 13 | import 'hardhat-exposed'; 14 | import 'hardhat-gas-reporter'; 15 | import 'hardhat-linearization'; 16 | import 'hardhat-spdx-license-identifier'; 17 | import { HardhatUserConfig } from 'hardhat/types'; 18 | import 'solidity-coverage'; 19 | 20 | const config: HardhatUserConfig = { 21 | networks: { 22 | hardhat: { 23 | allowUnlimitedContractSize: true, 24 | }, 25 | }, 26 | 27 | solidity: { 28 | version: '0.8.29', 29 | settings: { 30 | evmVersion: 'cancun', 31 | optimizer: { 32 | enabled: true, 33 | runs: 200, 34 | }, 35 | }, 36 | }, 37 | 38 | abiExporter: { 39 | runOnCompile: true, 40 | clear: true, 41 | flat: true, 42 | // do not export internal or test ABIs, including those generated by hardhat-exposed 43 | except: ['_.*', '.*Test$', '[$].*'], 44 | }, 45 | 46 | gasReporter: { 47 | enabled: true, 48 | reportPureAndViewMethods: true, 49 | outputFile: './gasreport.txt', 50 | }, 51 | 52 | spdxLicenseIdentifier: { 53 | overwrite: false, 54 | runOnCompile: true, 55 | }, 56 | }; 57 | 58 | export default config; 59 | -------------------------------------------------------------------------------- /test/cryptography/MerkleProof.ts: -------------------------------------------------------------------------------- 1 | import { 2 | $MerkleProof, 3 | $MerkleProof__factory, 4 | } from '@solidstate/typechain-types'; 5 | import { expect } from 'chai'; 6 | import { ethers } from 'hardhat'; 7 | import keccak256 from 'keccak256'; 8 | import { MerkleTree } from 'merkletreejs'; 9 | 10 | describe('MerkleProof', () => { 11 | let instance: $MerkleProof; 12 | 13 | beforeEach(async () => { 14 | const [deployer] = await ethers.getSigners(); 15 | instance = await new $MerkleProof__factory(deployer).deploy(); 16 | }); 17 | 18 | describe('#verify(bytes32[],bytes32,bytes32)', () => { 19 | it('returns true if proof is valid', async () => { 20 | const leaves = ['1', '2', '3']; 21 | const tree = new MerkleTree(leaves, keccak256, { 22 | hashLeaves: true, 23 | sortPairs: true, 24 | }); 25 | const root = tree.getHexRoot(); 26 | 27 | for (const leaf of leaves) { 28 | const proof = tree.getHexProof(keccak256(leaf)); 29 | 30 | expect(await instance.$verify.staticCall(proof, root, keccak256(leaf))) 31 | .to.be.true; 32 | } 33 | }); 34 | 35 | it('returns false if proof is invalid', async () => { 36 | const leaves = ['1', '2', '3']; 37 | const tree = new MerkleTree(leaves, keccak256, { 38 | hashLeaves: true, 39 | sortPairs: true, 40 | }); 41 | const root = tree.getHexRoot(); 42 | 43 | const proof = tree.getHexProof(keccak256(leaves[0])); 44 | 45 | expect(await instance.$verify.staticCall(proof, root, keccak256('4'))).to 46 | .be.false; 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /contracts/proxy/diamond/readable/DiamondProxyReadable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { IERC2535DiamondLoupe } from '../../../interfaces/IERC2535DiamondLoupe.sol'; 6 | import { Introspectable } from '../../../introspection/Introspectable.sol'; 7 | import { _DiamondProxyReadable } from './_DiamondProxyReadable.sol'; 8 | import { IDiamondProxyReadable } from './IDiamondProxyReadable.sol'; 9 | 10 | /** 11 | * @title EIP-2535 "Diamond" proxy introspection contract 12 | */ 13 | abstract contract DiamondProxyReadable is 14 | IDiamondProxyReadable, 15 | _DiamondProxyReadable, 16 | Introspectable 17 | { 18 | /** 19 | * @inheritdoc IERC2535DiamondLoupe 20 | */ 21 | function facets() external view returns (Facet[] memory diamondFacets) { 22 | diamondFacets = _facets(); 23 | } 24 | 25 | /** 26 | * @inheritdoc IERC2535DiamondLoupe 27 | */ 28 | function facetFunctionSelectors( 29 | address facet 30 | ) external view returns (bytes4[] memory selectors) { 31 | selectors = _facetFunctionSelectors(facet); 32 | } 33 | 34 | /** 35 | * @inheritdoc IERC2535DiamondLoupe 36 | */ 37 | function facetAddresses() 38 | external 39 | view 40 | returns (address[] memory addresses) 41 | { 42 | addresses = _facetAddresses(); 43 | } 44 | 45 | /** 46 | * @inheritdoc IERC2535DiamondLoupe 47 | */ 48 | function facetAddress( 49 | bytes4 selector 50 | ) external view returns (address facet) { 51 | facet = _facetAddress(selector); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /contracts/storage/ERC20Storage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { sslot } from '../data/StorageSlot.sol'; 6 | 7 | library ERC20Storage { 8 | struct Snapshots { 9 | uint256[] ids; 10 | uint256[] values; 11 | } 12 | 13 | /** 14 | * @custom:storage-location erc7201:solidstate.layout.ERC20 15 | */ 16 | struct Layout { 17 | mapping(address account => uint256 balance) balances; 18 | mapping(address holder => mapping(address spender => uint256 allowance)) allowances; 19 | uint256 totalSupply; 20 | string name; 21 | string symbol; 22 | uint8 decimals; 23 | mapping(address account => Snapshots balanceSnapshots) accountBalanceSnapshots; 24 | Snapshots totalSupplySnapshots; 25 | uint256 snapshotId; 26 | mapping(uint8 restrictionCode => string restrictionMessage) erc1404RestrictionMessages; 27 | mapping(address account => uint256 nonce) erc2612Nonces; 28 | address erc4626Asset; 29 | } 30 | 31 | sslot internal constant DEFAULT_STORAGE_SLOT = 32 | sslot.wrap( 33 | keccak256( 34 | abi.encode( 35 | uint256(keccak256(bytes('solidstate.layout.ERC20'))) - 1 36 | ) 37 | ) & ~bytes32(uint256(0xff)) 38 | ); 39 | 40 | function layout() internal pure returns (Layout storage $) { 41 | $ = layout(DEFAULT_STORAGE_SLOT); 42 | } 43 | 44 | function layout(sslot slot) internal pure returns (Layout storage $) { 45 | assembly { 46 | $.slot := slot 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /contracts/access/pausable/_Pausable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.24; 4 | 5 | import { _Context } from '../../meta/_Context.sol'; 6 | import { PausableStorage } from '../../storage/PausableStorage.sol'; 7 | import { _IPausable } from './_IPausable.sol'; 8 | 9 | /** 10 | * @title Internal functions for Pausable security control module. 11 | */ 12 | abstract contract _Pausable is _IPausable, _Context { 13 | modifier whenNotPaused() { 14 | if (_paused()) revert Pausable__Paused(); 15 | _; 16 | } 17 | 18 | modifier whenPaused() { 19 | if (!_paused()) revert Pausable__NotPaused(); 20 | _; 21 | } 22 | 23 | /** 24 | * @notice query whether contract is paused 25 | * @return status whether contract is paused 26 | */ 27 | function _paused() internal view virtual returns (bool status) { 28 | status = PausableStorage 29 | .layout(PausableStorage.DEFAULT_STORAGE_SLOT) 30 | .paused; 31 | } 32 | 33 | /** 34 | * @notice Triggers paused state, when contract is unpaused. 35 | */ 36 | function _pause() internal virtual whenNotPaused { 37 | PausableStorage 38 | .layout(PausableStorage.DEFAULT_STORAGE_SLOT) 39 | .paused = true; 40 | emit Paused(_msgSender()); 41 | } 42 | 43 | /** 44 | * @notice Triggers unpaused state, when contract is paused. 45 | */ 46 | function _unpause() internal virtual whenPaused { 47 | delete PausableStorage 48 | .layout(PausableStorage.DEFAULT_STORAGE_SLOT) 49 | .paused; 50 | emit Unpaused(_msgSender()); 51 | } 52 | } 53 | --------------------------------------------------------------------------------