Skip to content

Commit

Permalink
Custom errors, etc (#619)
Browse files Browse the repository at this point in the history
* custom error for extensions

* contract publisher

* legacy contracts

* custom error for CurrencyTransferLib

* efficient hash function MerkleProof

* Pack without forwarder

* fix test

* fix tests

* fix btt tests

* extension tests

* extension tests

* test pack

* more btt

* more tests

* drop prebuilt tests

* fix lint
  • Loading branch information
kumaryash90 authored Feb 26, 2024
1 parent effd208 commit 8959088
Show file tree
Hide file tree
Showing 81 changed files with 1,049 additions and 741 deletions.
27 changes: 21 additions & 6 deletions contracts/extension/BatchMintMetadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ pragma solidity ^0.8.0;
*/

contract BatchMintMetadata {
/// @dev Invalid index for batch
error BatchMintInvalidBatchId(uint256 index);

/// @dev Invalid token
error BatchMintInvalidTokenId(uint256 tokenId);

/// @dev Metadata frozen
error BatchMintMetadataFrozen(uint256 batchId);

/// @dev Largest tokenId of each batch of tokens with the same baseURI + 1 {ex: batchId 100 at position 0 includes tokens 0-99}
uint256[] private batchIds;

Expand Down Expand Up @@ -46,7 +55,7 @@ contract BatchMintMetadata {
*/
function getBatchIdAtIndex(uint256 _index) public view returns (uint256) {
if (_index >= getBaseURICount()) {
revert("Invalid index");
revert BatchMintInvalidBatchId(_index);
}
return batchIds[_index];
}
Expand All @@ -65,7 +74,7 @@ contract BatchMintMetadata {
}
}

revert("Invalid tokenId");
revert BatchMintInvalidTokenId(_tokenId);
}

/// @dev Returns the baseURI for a token. The intended metadata URI for the token is baseURI + tokenId.
Expand All @@ -78,7 +87,8 @@ contract BatchMintMetadata {
return baseURI[indices[i]];
}
}
revert("Invalid tokenId");

revert BatchMintInvalidTokenId(_tokenId);
}

/// @dev returns the starting tokenId of a given batchId.
Expand All @@ -94,20 +104,25 @@ contract BatchMintMetadata {
return 0;
}
}
revert("Invalid batchId");

revert BatchMintInvalidBatchId(_batchID);
}

/// @dev Sets the base URI for the batch of tokens with the given batchId.
function _setBaseURI(uint256 _batchId, string memory _baseURI) internal {
require(!batchFrozen[_batchId], "Batch frozen");
if (batchFrozen[_batchId]) {
revert BatchMintMetadataFrozen(_batchId);
}
baseURI[_batchId] = _baseURI;
emit BatchMetadataUpdate(_getBatchStartId(_batchId), _batchId);
}

/// @dev Freezes the base URI for the batch of tokens with the given batchId.
function _freezeBaseURI(uint256 _batchId) internal {
string memory baseURIForBatch = baseURI[_batchId];
require(bytes(baseURIForBatch).length > 0, "Invalid batch");
if (bytes(baseURIForBatch).length == 0) {
revert BatchMintInvalidBatchId(_batchId);
}
batchFrozen[_batchId] = true;
emit MetadataFrozen();
}
Expand Down
5 changes: 4 additions & 1 deletion contracts/extension/ContractMetadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import "./interface/IContractMetadata.sol";
*/

abstract contract ContractMetadata is IContractMetadata {
/// @dev The sender is not authorized to perform the action
error ContractMetadataUnauthorized();

/// @notice Returns the contract metadata URI.
string public override contractURI;

Expand All @@ -26,7 +29,7 @@ abstract contract ContractMetadata is IContractMetadata {
*/
function setContractURI(string memory _uri) external override {
if (!_canSetContractURI()) {
revert("Not authorized");
revert ContractMetadataUnauthorized();
}

_setupContractURI(_uri);
Expand Down
15 changes: 13 additions & 2 deletions contracts/extension/DelayedReveal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import "./interface/IDelayedReveal.sol";
*/

abstract contract DelayedReveal is IDelayedReveal {
/// @dev The contract doesn't have any url to be delayed revealed
error DelayedRevealNothingToReveal();

/// @dev The result of the returned an incorrect hash
error DelayedRevealIncorrectResultHash(bytes32 expected, bytes32 actual);

/// @dev Mapping from tokenId of a batch of tokens => to delayed reveal data.
mapping(uint256 => bytes) public encryptedData;

Expand All @@ -34,14 +40,19 @@ abstract contract DelayedReveal is IDelayedReveal {
function getRevealURI(uint256 _batchId, bytes calldata _key) public view returns (string memory revealedURI) {
bytes memory data = encryptedData[_batchId];
if (data.length == 0) {
revert("Nothing to reveal");
revert DelayedRevealNothingToReveal();
}

(bytes memory encryptedURI, bytes32 provenanceHash) = abi.decode(data, (bytes, bytes32));

revealedURI = string(encryptDecrypt(encryptedURI, _key));

require(keccak256(abi.encodePacked(revealedURI, _key, block.chainid)) == provenanceHash, "Incorrect key");
if (keccak256(abi.encodePacked(revealedURI, _key, block.chainid)) != provenanceHash) {
revert DelayedRevealIncorrectResultHash(
provenanceHash,
keccak256(abi.encodePacked(revealedURI, _key, block.chainid))
);
}
}

/**
Expand Down
44 changes: 37 additions & 7 deletions contracts/extension/Drop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ import "./interface/IDrop.sol";
import "../lib/MerkleProof.sol";

abstract contract Drop is IDrop {
/// @dev The sender is not authorized to perform the action
error DropUnauthorized();

/// @dev Exceeded the max token total supply
error DropExceedMaxSupply();

/// @dev No active claim condition
error DropNoActiveCondition();

/// @dev Claim condition invalid currency or price
error DropClaimInvalidTokenPrice(
address expectedCurrency,
uint256 expectedPricePerToken,
address actualCurrency,
uint256 actualExpectedPricePerToken
);

/// @dev Claim condition exceeded limit
error DropClaimExceedLimit(uint256 expected, uint256 actual);

/// @dev Claim condition exceeded max supply
error DropClaimExceedMaxSupply(uint256 expected, uint256 actual);

/// @dev Claim condition not started yet
error DropClaimNotStarted(uint256 expected, uint256 actual);

/*///////////////////////////////////////////////////////////////
State variables
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -54,7 +80,7 @@ abstract contract Drop is IDrop {
bool _resetClaimEligibility
) external virtual override {
if (!_canSetClaimConditions()) {
revert("Not authorized");
revert DropUnauthorized();
}

uint256 existingStartIndex = claimCondition.currentStartId;
Expand All @@ -81,7 +107,7 @@ abstract contract Drop is IDrop {

uint256 supplyClaimedAlready = claimCondition.conditions[newStartIndex + i].supplyClaimed;
if (supplyClaimedAlready > _conditions[i].maxClaimableSupply) {
revert("max supply claimed");
revert DropExceedMaxSupply();
}

claimCondition.conditions[newStartIndex + i] = _conditions[i];
Expand Down Expand Up @@ -163,18 +189,22 @@ abstract contract Drop is IDrop {
uint256 supplyClaimedByWallet = claimCondition.supplyClaimedByWallet[_conditionId][_claimer];

if (_currency != claimCurrency || _pricePerToken != claimPrice) {
revert("!PriceOrCurrency");
revert DropClaimInvalidTokenPrice(_currency, _pricePerToken, claimCurrency, claimPrice);
}

if (_quantity == 0 || (_quantity + supplyClaimedByWallet > claimLimit)) {
revert("!Qty");
revert DropClaimExceedLimit(claimLimit, _quantity + supplyClaimedByWallet);
}

if (currentClaimPhase.supplyClaimed + _quantity > currentClaimPhase.maxClaimableSupply) {
revert("!MaxSupply");
revert DropClaimExceedMaxSupply(
currentClaimPhase.maxClaimableSupply,
currentClaimPhase.supplyClaimed + _quantity
);
}

if (currentClaimPhase.startTimestamp > block.timestamp) {
revert("cant claim yet");
revert DropClaimNotStarted(currentClaimPhase.startTimestamp, block.timestamp);
}
}

Expand All @@ -186,7 +216,7 @@ abstract contract Drop is IDrop {
}
}

revert("!CONDITION.");
revert DropNoActiveCondition();
}

/// @dev Returns the claim condition at the given uid.
Expand Down
43 changes: 36 additions & 7 deletions contracts/extension/Drop1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ import "./interface/IDrop1155.sol";
import "../lib/MerkleProof.sol";

abstract contract Drop1155 is IDrop1155 {
/// @dev The sender is not authorized to perform the action
error DropUnauthorized();

/// @dev Exceeded the max token total supply
error DropExceedMaxSupply();

/// @dev No active claim condition
error DropNoActiveCondition();

/// @dev Claim condition invalid currency or price
error DropClaimInvalidTokenPrice(
address expectedCurrency,
uint256 expectedPricePerToken,
address actualCurrency,
uint256 actualExpectedPricePerToken
);

/// @dev Claim condition exceeded limit
error DropClaimExceedLimit(uint256 expected, uint256 actual);

/// @dev Claim condition exceeded max supply
error DropClaimExceedMaxSupply(uint256 expected, uint256 actual);

/// @dev Claim condition not started yet
error DropClaimNotStarted(uint256 expected, uint256 actual);

/*///////////////////////////////////////////////////////////////
State variables
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -64,7 +90,7 @@ abstract contract Drop1155 is IDrop1155 {
bool _resetClaimEligibility
) external virtual override {
if (!_canSetClaimConditions()) {
revert("Not authorized");
revert DropUnauthorized();
}
ClaimConditionList storage conditionList = claimCondition[_tokenId];
uint256 existingStartIndex = conditionList.currentStartId;
Expand All @@ -91,7 +117,7 @@ abstract contract Drop1155 is IDrop1155 {

uint256 supplyClaimedAlready = conditionList.conditions[newStartIndex + i].supplyClaimed;
if (supplyClaimedAlready > _conditions[i].maxClaimableSupply) {
revert("max supply claimed");
revert DropExceedMaxSupply();
}

conditionList.conditions[newStartIndex + i] = _conditions[i];
Expand Down Expand Up @@ -174,19 +200,22 @@ abstract contract Drop1155 is IDrop1155 {
uint256 supplyClaimedByWallet = claimCondition[_tokenId].supplyClaimedByWallet[_conditionId][_claimer];

if (_currency != claimCurrency || _pricePerToken != claimPrice) {
revert("!PriceOrCurrency");
revert DropClaimInvalidTokenPrice(_currency, _pricePerToken, claimCurrency, claimPrice);
}

if (_quantity == 0 || (_quantity + supplyClaimedByWallet > claimLimit)) {
revert("!Qty");
revert DropClaimExceedLimit(claimLimit, _quantity + supplyClaimedByWallet);
}

if (currentClaimPhase.supplyClaimed + _quantity > currentClaimPhase.maxClaimableSupply) {
revert("!MaxSupply");
revert DropClaimExceedMaxSupply(
currentClaimPhase.maxClaimableSupply,
currentClaimPhase.supplyClaimed + _quantity
);
}

if (currentClaimPhase.startTimestamp > block.timestamp) {
revert("cant claim yet");
revert DropClaimNotStarted(currentClaimPhase.startTimestamp, block.timestamp);
}
}

Expand All @@ -199,7 +228,7 @@ abstract contract Drop1155 is IDrop1155 {
}
}

revert("!CONDITION.");
revert DropNoActiveCondition();
}

/// @dev Returns the claim condition at the given uid.
Expand Down
41 changes: 35 additions & 6 deletions contracts/extension/DropSinglePhase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ import "./interface/IDropSinglePhase.sol";
import "../lib/MerkleProof.sol";

abstract contract DropSinglePhase is IDropSinglePhase {
/// @dev The sender is not authorized to perform the action
error DropUnauthorized();

/// @dev Exceeded the max token total supply
error DropExceedMaxSupply();

/// @dev No active claim condition
error DropNoActiveCondition();

/// @dev Claim condition invalid currency or price
error DropClaimInvalidTokenPrice(
address expectedCurrency,
uint256 expectedPricePerToken,
address actualCurrency,
uint256 actualExpectedPricePerToken
);

/// @dev Claim condition exceeded limit
error DropClaimExceedLimit(uint256 expected, uint256 actual);

/// @dev Claim condition exceeded max supply
error DropClaimExceedMaxSupply(uint256 expected, uint256 actual);

/// @dev Claim condition not started yet
error DropClaimNotStarted(uint256 expected, uint256 actual);

/*///////////////////////////////////////////////////////////////
State variables
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -63,7 +89,7 @@ abstract contract DropSinglePhase is IDropSinglePhase {
/// @dev Lets a contract admin set claim conditions.
function setClaimConditions(ClaimCondition calldata _condition, bool _resetClaimEligibility) external override {
if (!_canSetClaimConditions()) {
revert("Not authorized");
revert DropUnauthorized();
}

bytes32 targetConditionId = conditionId;
Expand All @@ -75,7 +101,7 @@ abstract contract DropSinglePhase is IDropSinglePhase {
}

if (supplyClaimedAlready > _condition.maxClaimableSupply) {
revert("max supply claimed");
revert DropExceedMaxSupply();
}

claimCondition = ClaimCondition({
Expand Down Expand Up @@ -140,19 +166,22 @@ abstract contract DropSinglePhase is IDropSinglePhase {
uint256 _supplyClaimedByWallet = supplyClaimedByWallet[conditionId][_claimer];

if (_currency != claimCurrency || _pricePerToken != claimPrice) {
revert("!PriceOrCurrency");
revert DropClaimInvalidTokenPrice(_currency, _pricePerToken, claimCurrency, claimPrice);
}

if (_quantity == 0 || (_quantity + _supplyClaimedByWallet > claimLimit)) {
revert("!Qty");
revert DropClaimExceedLimit(claimLimit, _quantity + _supplyClaimedByWallet);
}

if (currentClaimPhase.supplyClaimed + _quantity > currentClaimPhase.maxClaimableSupply) {
revert("!MaxSupply");
revert DropClaimExceedMaxSupply(
currentClaimPhase.maxClaimableSupply,
currentClaimPhase.supplyClaimed + _quantity
);
}

if (currentClaimPhase.startTimestamp > block.timestamp) {
revert("cant claim yet");
revert DropClaimNotStarted(currentClaimPhase.startTimestamp, block.timestamp);
}
}

Expand Down
Loading

0 comments on commit 8959088

Please sign in to comment.