ProjectOpenSea / operator-filter-registry

MIT License
312 stars 89 forks source link

Following the guide on `RevokableDefaultOperatorFiltererUpgradeable` but still not eligible for creator fees. #32

Closed pictta-mac closed 1 year ago

pictta-mac commented 1 year ago

https://goerli.etherscan.io/address/0xceeab5b8852e267a27f51799d892bad86e3baadd#code

I have been using code from 72b5d50d8e63d1be48a23a482aa3b165195587ab but my ERC721A-upgradable contract is still not eligible for creator fees on goerli

pictta-mac commented 1 year ago

The main code block is here `// SPDX-License-Identifier: MIT / ascii art
/ pragma solidity ^0.8.14;

import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import 'erc721a-upgradeable/contracts/ERC721AUpgradeable.sol'; import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol'; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import {RevokableDefaultOperatorFiltererUpgradeable} from "./opensea/upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol"; import {RevokableOperatorFiltererUpgradeable} from "./opensea/upgradeable/RevokableOperatorFiltererUpgradeable.sol";

contract GenesisSBT is ERC721AUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable, RevokableDefaultOperatorFiltererUpgradeable, OwnableUpgradeable { string public baseURI; string public tokenURISuffix; uint256 public constant MAX_SUPPLY = 10000;
uint256 public MAX_PER_ADDRESS; uint256 public constant earlyBirdSupply = 2000; uint256 public constant WLSupply = 3000; uint256 public mintStartAt; uint256 public mintEndAt; uint256 public FFEndAt; uint256 public WLEndAt; uint256 public totalMinted; uint256 public constant earlyBirdPrice = 0.00001 ether; uint256 public constant whitelistPrice = 0.00001 ether; uint256 public constant publicPrice = 0.000002 ether; bytes32 public merkleRoot; address public constant VAULT = 0x4962913E3b8Ae6f918eF004c73FbE82A2F19804a;

mapping(address => uint256) mintedAccounts;

using SafeERC20Upgradeable for IERC20Upgradeable;

function initialize(
    uint256 _MAX_PER_ADDRESS,
    string memory _coverBaseURI,
    string memory _tokenURISuffix,
    uint256 _mintStartAt,
    uint256 _mintEndAt,        
    bytes32 _merkleRoot,
    uint256 _FFEndAt,
    uint256 _WLEndAt
) initializerERC721A initializer public {
    __ERC721A_init('GenesisSBT', 'GSBT');
    __Ownable_init();
    __RevokableDefaultOperatorFilterer_init();

    baseURI = _coverBaseURI;
    tokenURISuffix = _tokenURISuffix;
    MAX_PER_ADDRESS = _MAX_PER_ADDRESS;
    mintStartAt = _mintStartAt;
    mintEndAt = _mintEndAt;
    merkleRoot = _merkleRoot;        
    FFEndAt = _FFEndAt;
    WLEndAt = _WLEndAt;
    totalMinted = 0;
}

// Utilities
function setNewMerkleRoot(bytes32 _newRoot) external onlyOwner {
    merkleRoot = _newRoot;
}

function _merkleTreeLeaf(address _address) internal pure returns (bytes32) {
    return keccak256((abi.encodePacked(_address)));
}

function _merkleTreeVerify(bytes32 _leaf, bytes32[] memory _proof) internal view returns(bool) {
    return MerkleProof.verify(_proof, merkleRoot, _leaf);
}

// Mint Setup
function setMintInfo(uint256 _mintStartAt, uint256 _mintEndAt, uint256 _FFEndAt, uint256 _WLEndAt) public onlyOwner {                
    mintStartAt = _mintStartAt;  // block.timestamp to start mint
    mintEndAt = _mintEndAt; // block.timestamp to end mint
    FFEndAt = _FFEndAt;
    WLEndAt = _WLEndAt;
}

// Mint
function mint(uint256 _quantity, bytes32[] calldata proof) external nonReentrant payable whenNotPaused {
    require(
        (mintStartAt <= block.timestamp && mintEndAt > block.timestamp), 
        "Mint is not active."
    );
    require(
        mintedAccounts[msg.sender] + _quantity <= MAX_PER_ADDRESS,
        "Sorry, you have minted all your quota."
    ); 
    require(
        totalMinted + _quantity <= MAX_SUPPLY,
        "ALL SOLD!"
    );  

    if(block.timestamp < WLEndAt) {
        require(_merkleTreeVerify(_merkleTreeLeaf(msg.sender), proof),
            "Sorry, you are not whitelisted for this round. Come back later!"
        );
        // Frens & Fam tier
        if(block.timestamp < FFEndAt) {
            require(
                totalMinted + _quantity <= earlyBirdSupply,
                "earlyBirdSupply round is sold out!"
            );
            require(
                msg.value == earlyBirdPrice * _quantity,
                "Insufficient payment."
            );                
        } else {
        // Fortune Cookies tier  
            require(
                totalMinted + _quantity <= earlyBirdSupply + WLSupply,
                "White list round is sold out!"
            );
            require(
                msg.value == whitelistPrice * _quantity,
                "Insufficient payment."
            );
        }
        _safeMint(msg.sender, _quantity);                              
    } else {
        // Public tier
        require(
            msg.value == publicPrice * _quantity,
            "Insufficient payment."
        );
        _safeMint(msg.sender, _quantity);
    }

    totalMinted += _quantity;        
    mintedAccounts[msg.sender] += _quantity;        
}

// Post Mint
function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
}

function setBaseURI(string memory _newBaseURI) external onlyOwner {
    baseURI = _newBaseURI;
}

function setTokenURISuffix(string memory _newTokenURISuffix) external onlyOwner {
    tokenURISuffix = _newTokenURISuffix;
}
function tokenURI(uint256 _tokenId) public view override returns(string memory) {
    return string.concat(super.tokenURI(_tokenId), tokenURISuffix);
}

// Fund Withdraw
function withdrawETH() external onlyOwner {
    require(VAULT != address(0), "Cant transfer to 0 address!");
    (bool withdrawSucceed, ) = payable(VAULT).call{ value: address(this).balance }("");
    require(withdrawSucceed, "Withdraw Failed");
}

function withdrawERC20(address _to, address _tokenContract, uint256 _amount) external onlyOwner {
    require(_to != address(0), "Cant transfer to 0 address!");
    IERC20Upgradeable tokenContract = IERC20Upgradeable(_tokenContract);
    tokenContract.safeTransfer(_to, _amount);
}

// Admin pause
function pause() external onlyOwner {
    _pause();
}

function unpause() external onlyOwner {
    _unpause();
}

// Opensea Operator filter registry
function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
    super.setApprovalForAll(operator, approved);
}

function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
    super.approve(operator, tokenId);
}

function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
    super.transferFrom(from, to, tokenId);
}

function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
    super.safeTransferFrom(from, to, tokenId);
}

function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
    public
    override
    onlyAllowedOperator(from)
{
    super.safeTransferFrom(from, to, tokenId, data);
}

function owner() public view virtual override (OwnableUpgradeable, RevokableOperatorFiltererUpgradeable) returns (address) {
    return OwnableUpgradeable.owner();
}

}`

gasshadow commented 1 year ago

I checked it, your proxy contract 0xCEFDe12dD1AFc544ca50e41d1c623140fEAd2647 already be registed to 0x000000000000AAeB6D7670E522A718067333cd4E contract, So I think it should be OK .

gasshadow commented 1 year ago

I get the same question. I call safeTransferFrom function to my contract with the black list address (0x00000000000111AbE46ff893f3B2fdF1F759a8A8,0x59728544B08AB483533076417FbBB2fD0B17CE3a,0xF849de01B080aDC3A814FaBE1E2087475cF2E354,0x2B2e8cDA09bBA9660dCA5cB6233787738Ad68329,0xf42aa99F011A1fA7CDA90E5E98b277E306BcA83e,0x024aC22ACdB367a3ae52A3D94aC6649fdc1f0779,0xFED24eC7E22f573c2e08AEF55aA6797Ca2b3A051), all results are 'execution reverted' and data like : 0xa8cf495d000000000000000000000000024ac22acdb367a3ae52a3d94ac6649fdc1f0779 which is the result by revert OperatorNotAllowed(msg.sender); .

So I'm sure my contract is ok and run by the right way. But in testnets.opensea.io , I can't set the creator fees

nidhhoggr commented 1 year ago

I have the same issue: the code is clearly implemented but is not eligible for creator fees on the testnet. can someone from OpenSea please address this?

operatorfilterer commented 1 year ago

Ingestion on Goerli should be fixed for new contracts - try redeploying, or sharing your address in #18 so we can re-validate. Closing in lieu of #18 - please post follow up in that issue.