Skip to content

Commit

Permalink
Merge pull request #313 from joinzien/passes
Browse files Browse the repository at this point in the history
Add support for passes
  • Loading branch information
Zoe Nolan authored Oct 24, 2023
2 parents 2675596 + 956b3f4 commit af0ad04
Show file tree
Hide file tree
Showing 12 changed files with 3,751 additions and 802 deletions.
890 changes: 889 additions & 1 deletion abi/expandednft_v1.json

Large diffs are not rendered by default.

952 changes: 951 additions & 1 deletion abi/expandednft_v2.json

Large diffs are not rendered by default.

816 changes: 815 additions & 1 deletion abi/expandednft_v3.json

Large diffs are not rendered by default.

100 changes: 96 additions & 4 deletions contracts/ExpandedNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
pragma solidity ^0.8.19;

import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import {IERC2981Upgradeable, IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {StringsUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";

import {IExpandedNFT} from "./IExpandedNFT.sol";
Expand Down Expand Up @@ -94,9 +94,23 @@ contract ExpandedNFT is
WhoCanMint whoCanMint;

// Mint counts for each address
mapping(address => uint256) mintCounts;
mapping(address => uint256) mintCounts;

// Annual pass address
IERC721Upgradeable annualPassAddress;

// Lifetime pass address
IERC721Upgradeable lifetimePassAddress;

// Annual pass discount
uint256 annualPassDiscount;

// Lifetime pass discount
uint256 lifetimePassDiscount;
}

uint256 private constant _HUNDRED_PERCENT_AS_BPS = 10000;

// Artists wallet address
address private _artistWallet;

Expand Down Expand Up @@ -206,6 +220,26 @@ contract ExpandedNFT is
return _pricing.generalMintLimit;
}

/// @dev returns the Annual pass address
function getAnnualPassAddress() public view returns (address) {
return address(_pricing.annualPassAddress);
}

/// @dev returns the Lifetime pass address
function getLifetimePassAddress() public view returns (address) {
return address(_pricing.lifetimePassAddress);
}

/// @dev returns the Annual pass discount
function getAnnualPassDiscount() public view returns (uint256) {
return _pricing.annualPassDiscount;
}

/// @dev returns the Lifetime pass discount
function getLifetimePassDiscount() public view returns (uint256) {
return _pricing.lifetimePassDiscount;
}

/// @dev returns mint limit for the address
function getMintLimit(address wallet) public view returns (uint256) {
if (wallet == owner()) {
Expand Down Expand Up @@ -320,7 +354,36 @@ contract ExpandedNFT is
function _paymentAmountCorrect(uint256 numberToBeMinted)
internal returns (bool)
{
if (msg.value == (price() * numberToBeMinted)) {
uint256 paymentAmount = price() * numberToBeMinted;

// Assuming Lifetime passes have a greeater or equal discount to the annual pass
if (address(_pricing.lifetimePassAddress) != address(0x0)) {
if (_pricing.lifetimePassAddress.balanceOf(msg.sender) > 0) {
uint256 discount = _HUNDRED_PERCENT_AS_BPS - _pricing.lifetimePassDiscount;
uint256 lifetimePassPaymentAmount = (paymentAmount * discount) / _HUNDRED_PERCENT_AS_BPS;

if (msg.value == lifetimePassPaymentAmount) {
return (true);
}

return (false);
}
}

if (address(_pricing.annualPassAddress) != address(0x0)) {
if (_pricing.annualPassAddress.balanceOf(msg.sender) > 0) {
uint256 discount = _HUNDRED_PERCENT_AS_BPS - _pricing.annualPassDiscount;
uint256 annualPassPaymentAmount = (paymentAmount * discount) / _HUNDRED_PERCENT_AS_BPS;

if (msg.value == annualPassPaymentAmount) {
return (true);
}

return (false);
}
}

if (msg.value == paymentAmount) {
return (true);
}

Expand Down Expand Up @@ -415,6 +478,23 @@ contract ExpandedNFT is
return currentToken;
}

/**
@param annualPassAddress Annual pass ERC721 token address. Can be null if no token is in use.
@param lifetimePassAddress Lifetime pass ERC721 token address. Can be null if no token is in use.
@param annualPassDiscount Annual pass discount in BPS.
@param lifetimePassDiscount Lifetime pass discount in BPS.
@dev Set various pricing related values
*/
function updateDiscounts(address annualPassAddress, address lifetimePassAddress, uint256 annualPassDiscount, uint256 lifetimePassDiscount) external onlyOwner {
require(annualPassDiscount <= _HUNDRED_PERCENT_AS_BPS, "Discount can not be greater than 100%");

Check warning on line 489 in contracts/ExpandedNFT.sol

View workflow job for this annotation

GitHub Actions / run-lint

Error message for require is too long: 37 counted / 32 allowed

Check warning on line 489 in contracts/ExpandedNFT.sol

View workflow job for this annotation

GitHub Actions / run-lint

Use Custom Errors instead of require statements
require(lifetimePassDiscount <= _HUNDRED_PERCENT_AS_BPS, "Discount can not be greater than 100%");

_pricing.annualPassAddress = IERC721Upgradeable(annualPassAddress);
_pricing.lifetimePassAddress = IERC721Upgradeable(lifetimePassAddress);
_pricing.annualPassDiscount = annualPassDiscount;
_pricing.lifetimePassDiscount = lifetimePassDiscount;
}

/**
@param _royaltyBPS BPS of the royalty set on the contract. Can be 0 for no royalty.
@param _splitBPS BPS of the royalty set on the contract. Can be 0 for no royalty.
Expand Down Expand Up @@ -627,7 +707,19 @@ contract ExpandedNFT is
if (_pricing.whoCanMint == WhoCanMint.ALLOWLIST) {
if (_pricing.allowListMinters[msg.sender]) {
return true;
}
}

if (address(_pricing.lifetimePassAddress) != address(0x0)) {
if (_pricing.lifetimePassAddress.balanceOf(msg.sender) > 0) {
return (true);
}
}

if (address(_pricing.annualPassAddress) != address(0x0)) {
if (_pricing.annualPassAddress.balanceOf(msg.sender) > 0) {
return (true);
}
}
}

return false;
Expand Down
30 changes: 30 additions & 0 deletions contracts/TestPassOne.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-3.0

/**
Test pass ERC721 contract
*/

pragma solidity ^0.8.19;

import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import {CountersUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol";

contract TestPassOne is ERC721Upgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
CountersUpgradeable.Counter private _tokenIds;

function initialize() public initializer {
__ERC721_init("Test Pass One", "TPO");
}

function mint(address player) public returns (uint256) {
_tokenIds.increment();

uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);

return newItemId;
}
}
30 changes: 30 additions & 0 deletions contracts/TestPassTwo.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-3.0

/**
Test pass ERC721 contract
*/

pragma solidity ^0.8.19;

import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import {CountersUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol";

contract TestPassTwo is ERC721Upgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
CountersUpgradeable.Counter private _tokenIds;

function initialize() public initializer {
__ERC721_init("Test Pass One", "TPO");
}

function mint(address player) public returns (uint256) {
_tokenIds.increment();

uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);

return newItemId;
}
}
11 changes: 11 additions & 0 deletions deploy/03_testpassone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = async ({ getNamedAccounts, deployments }: any ) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

await deploy("TestPassOne", {
from: deployer,
log: true,
});
};

module.exports.tags = ["TestPassOne"];
11 changes: 11 additions & 0 deletions deploy/04_testpasstwo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = async ({ getNamedAccounts, deployments }: any ) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

await deploy("TestPassTwo", {
from: deployer,
log: true,
});
};

module.exports.tags = ["TestPassTwo"];
Loading

0 comments on commit af0ad04

Please sign in to comment.