Those two files allow to have easy gas-less trading on OpenSea
OpenSea Proxyregistry addresses:
Mainnet: 0xa5409ec958c83c3f309868babaca7c86dcb077c1
Rinkeby: 0xf57b2c51ded3a29e6891aba85459d600256cf317
Those two files allow to have easy gas-less trading on OpenSea
OpenSea Proxyregistry addresses:
Mainnet: 0xa5409ec958c83c3f309868babaca7c86dcb077c1
Rinkeby: 0xf57b2c51ded3a29e6891aba85459d600256cf317
| //SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.0; | |
| /// @title OpenSea contract helper that defines a few things | |
| /// @author Simon Fremaux (@dievardump) | |
| /// @dev This is a contract used to add OpenSea's | |
| /// gas-less trading and contractURI support | |
| contract BaseOpenSea { | |
| string private _contractURI; | |
| address private _proxyRegistry; | |
| /// @notice Returns the contract URI function. Used on OpenSea to get details | |
| // about a contract (owner, royalties etc...) | |
| function contractURI() public view returns (string memory) { | |
| return _contractURI; | |
| } | |
| /// @notice Returns the current OS proxyRegistry address registered | |
| function proxyRegistry() public view returns (address) { | |
| return _proxyRegistry; | |
| } | |
| /// @notice Helper allowing OpenSea gas-less trading by verifying who's operator | |
| /// for owner | |
| /// @dev Allows to check if `operator` is owner's OpenSea proxy on eth mainnet / rinkeby | |
| /// or to check if operator is OpenSea's proxy contract on Polygon and Mumbai | |
| /// @param owner the owner we check for | |
| /// @param operator the operator (proxy) we check for | |
| function isOwnersOpenSeaProxy(address owner, address operator) | |
| public | |
| view | |
| returns (bool) | |
| { | |
| address proxyRegistry_ = _proxyRegistry; | |
| // if we have a proxy registry | |
| if (proxyRegistry_ != address(0)) { | |
| // on ethereum mainnet or rinkeby use "ProxyRegistry" to | |
| // get owner's proxy | |
| if (block.chainid == 1 || block.chainid == 4) { | |
| return | |
| address(ProxyRegistry(proxyRegistry_).proxies(owner)) == | |
| operator; | |
| } else if (block.chainid == 137 || block.chainid == 80001) { | |
| // on Polygon and Mumbai just try with OpenSea's proxy contract | |
| // https://docs.opensea.io/docs/polygon-basic-integration | |
| return proxyRegistry_ == operator; | |
| } | |
| } | |
| return false; | |
| } | |
| /// @dev Internal function to set the _contractURI | |
| /// @param contractURI_ the new contract uri | |
| function _setContractURI(string memory contractURI_) internal { | |
| _contractURI = contractURI_; | |
| } | |
| /// @dev Internal function to set the _proxyRegistry | |
| /// @param proxyRegistryAddress the new proxy registry address | |
| function _setOpenSeaRegistry(address proxyRegistryAddress) internal { | |
| _proxyRegistry = proxyRegistryAddress; | |
| } | |
| } | |
| contract OwnableDelegateProxy {} | |
| contract ProxyRegistry { | |
| mapping(address => OwnableDelegateProxy) public proxies; | |
| } | 
| //SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.0; | |
| import "@openzeppelin/contracts/access/Ownable.sol"; | |
| import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; | |
| import "./OpenSea/BaseOpenSea.sol"; | |
| /// @title Example of usage of BaseOpenSea | |
| /// @author Simon Fremaux (@dievardump) | |
| /// @notice This contract is only an example of how I implement BaseOpenSea | |
| contract MyERC1155 is | |
| Ownable, | |
| ERC1155, | |
| BaseOpenSea | |
| { | |
| /// @notice constructor | |
| /// @param uri_ - the contract base uri | |
| /// @param openSeaProxyRegistry - the address of OpenSea Proxy Registry | |
| /// @param contractURI_ - the contract metadata URI (https://docs.opensea.io/docs/contract-level-metadata) | |
| constructor(string memory uri_, address openSeaProxyRegistry, string memory contractURI_) ERC1155(uri_) { | |
| if (openSeaProxyRegistry != address(0)) { | |
| _setOpenSeaRegistry(openSeaProxyRegistry); | |
| } | |
| if (bytes(contractURI_).length > 0) { | |
| _setContractURI(contractURI_); | |
| } | |
| } | |
| /// @notice Allows gas-less trading on OpenSea by safelisting the ProxyRegistry of the user | |
| /// @dev Override isApprovedForAll to check first if current operator is owner's OpenSea proxy | |
| /// @inheritdoc ERC1155 | |
| function isApprovedForAll(address owner, address operator) | |
| public | |
| view | |
| override | |
| returns (bool) | |
| { | |
| // allows gas less trading on OpenSea | |
| return super.isApprovedForAll(owner, operator) || isOwnersOpenSeaProxy(owner, operator); | |
| } | |
| /// @notice Helper for the owner of the contract to set the new contract URI | |
| /// @dev caller needs to be owner | |
| /// @param contractURI_ new contract URI | |
| function setContractURI(string memory contractURI_) external onlyOwner { | |
| _setContractURI(contractURI_); | |
| } | |
| } | 
| //SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.0; | |
| import "@openzeppelin/contracts/access/Ownable.sol"; | |
| import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
| import "./OpenSea/BaseOpenSea.sol"; | |
| /// @title Example of usage of BaseOpenSea | |
| /// @author Simon Fremaux (@dievardump) | |
| /// @notice This contract is only an example of how I implement BaseOpenSea | |
| contract MyERC721 is | |
| Ownable, | |
| ERC721, | |
| BaseOpenSea | |
| { | |
| /// @notice constructor | |
| /// @param openSeaProxyRegistry - the address of OpenSea Proxy Registry | |
| /// @param contractURI_ - the contract metadata URI (https://docs.opensea.io/docs/contract-level-metadata) | |
| constructor(address openSeaProxyRegistry, string memory contractURI_) ERC721('MyNFT', 'NFT') { | |
| if (openSeaProxyRegistry != address(0)) { | |
| _setOpenSeaRegistry(openSeaProxyRegistry); | |
| } | |
| if (bytes(contractURI_).length > 0) { | |
| _setContractURI(contractURI_); | |
| } | |
| } | |
| /// @notice Allows gas-less trading on OpenSea by safelisting the ProxyRegistry of the user | |
| /// @dev Override isApprovedForAll to check first if current operator is owner's OpenSea proxy | |
| /// @inheritdoc ERC721 | |
| function isApprovedForAll(address owner, address operator) | |
| public | |
| view | |
| override | |
| returns (bool) | |
| { | |
| // allows gas less trading on OpenSea | |
| return super.isApprovedForAll(owner, operator) || isOwnersOpenSeaProxy(owner, operator); | |
| } | |
| /// @notice Helper for the owner of the contract to set the new contract URI | |
| /// @dev caller needs to be owner | |
| /// @param contractURI_ new contract URI | |
| function setContractURI(string memory contractURI_) external onlyOwner { | |
| _setContractURI(contractURI_); | |
| } | |
| } |