Skip to content

Instantly share code, notes, and snippets.

@nazt
Forked from dievardump/README.md
Created January 23, 2022 21:43
Show Gist options
  • Save nazt/5379d82da5f71af4d9abcafaa23d48ca to your computer and use it in GitHub Desktop.
Save nazt/5379d82da5f71af4d9abcafaa23d48ca to your computer and use it in GitHub Desktop.
Base file I use for my mainnet contracts to be compatible with OpenSea

Gas-Less trading

Those two files allow to have easy gas-less trading on OpenSea

Registries

OpenSea Proxyregistry addresses:

Mainnet: 0xa5409ec958c83c3f309868babaca7c86dcb077c1

Rinkeby: 0xf57b2c51ded3a29e6891aba85459d600256cf317

Contract level metadata with contractURI()

https://docs.opensea.io/docs/contract-level-metadata

//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_);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment