Skip to content

Commit

Permalink
Two minor changes
Browse files Browse the repository at this point in the history
1. `initOwner` used in event logs during initialization rather than `tx.origin`
2. ERC-7160 compliant contracts now have a setting where they can change the behavior of the returned metadata when unpinned
  • Loading branch information
mpeyfuss committed Mar 14, 2024
1 parent 4aced70 commit 1b77fb9
Show file tree
Hide file tree
Showing 15 changed files with 701 additions and 108 deletions.
19 changes: 19 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"wake.compiler.solc.remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-upgradeable/=lib/tl-sol-tools/lib/openzeppelin-contracts-upgradeable/contracts/",
"openzeppelin/=lib/tl-sol-tools/lib/openzeppelin-contracts/contracts/",
"tl-sol-tools/=lib/tl-sol-tools/src/",
"@manifoldxyz/libraries-solidity/=lib/tl-sol-tools/lib/royalty-registry-solidity/lib/libraries-solidity/",
"@openzeppelin/contracts-upgradeable/=lib/tl-sol-tools/lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/tl-sol-tools/lib/openzeppelin-contracts/contracts/",
"create2-helpers/=lib/tl-sol-tools/lib/royalty-registry-solidity/lib/create2-helpers/",
"create2-scripts/=lib/tl-sol-tools/lib/royalty-registry-solidity/lib/create2-helpers/script/",
"erc4626-tests/=lib/tl-sol-tools/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"libraries-solidity/=lib/tl-sol-tools/lib/royalty-registry-solidity/lib/libraries-solidity/contracts/",
"royalty-registry-solidity/=lib/tl-sol-tools/lib/royalty-registry-solidity/",
"openzeppelin-contracts-upgradeable/=lib/tl-sol-tools/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/tl-sol-tools/lib/openzeppelin-contracts/"
]
}
11 changes: 5 additions & 6 deletions src/erc-1155/ERC1155TL.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {IERC1155TL} from "./IERC1155TL.sol";
/// @title ERC1155TL.sol
/// @notice Sovereign ERC-1155 Creator Contract with Story Inscriptions
/// @author transientlabs.xyz
/// @custom:version 3.0.1
/// @custom:version 3.1.0
contract ERC1155TL is
ERC1155Upgradeable,
EIP2981TLUpgradeable,
Expand All @@ -34,7 +34,7 @@ contract ERC1155TL is
State Variables
//////////////////////////////////////////////////////////////////////////*/

string public constant VERSION = "3.0.1";
string public constant VERSION = "3.1.0";
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
uint256 private _counter;
Expand Down Expand Up @@ -91,7 +91,6 @@ contract ERC1155TL is
Initializer
//////////////////////////////////////////////////////////////////////////*/

/// @dev `tx.origin` is used in the events here as these can be deployed via contract factories and we want to capture the true sender
/// @param name_ The name of the 721 contract
/// @param symbol_ The symbol of the 721 contract
/// @param personalization A string to emit as a collection story. Can be ASCII art or something else that is a personalization of the contract.
Expand Down Expand Up @@ -126,15 +125,15 @@ contract ERC1155TL is

// story
storyEnabled = enableStory;
emit StoryStatusUpdate(tx.origin, enableStory);
emit StoryStatusUpdate(initOwner, enableStory);

// blocklist
blocklistRegistry = IBlockListRegistry(initBlockListRegistry);
emit BlockListRegistryUpdate(tx.origin, address(0), initBlockListRegistry);
emit BlockListRegistryUpdate(initOwner, address(0), initBlockListRegistry);

// emit personalization as collection story
if (bytes(personalization).length > 0) {
emit CollectionStory(tx.origin, tx.origin.toHexString(), personalization);
emit CollectionStory(initOwner, initOwner.toHexString(), personalization);
}
}

Expand Down
13 changes: 6 additions & 7 deletions src/erc-721/ERC721TL.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {IERC721TL} from "./IERC721TL.sol";
/// @title ERC721TL.sol
/// @notice Sovereign ERC-721 Creator Contract with Synergy and Story Inscriptions
/// @author transientlabs.xyz
/// @custom:version 3.0.1
/// @custom:version 3.1.0
contract ERC721TL is
ERC721Upgradeable,
OwnableAccessControlUpgradeable,
Expand Down Expand Up @@ -49,7 +49,7 @@ contract ERC721TL is
State Variables
//////////////////////////////////////////////////////////////////////////*/

string public constant VERSION = "3.0.1";
string public constant VERSION = "3.1.0";
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
uint256 private _counter; // token ids
Expand Down Expand Up @@ -108,7 +108,6 @@ contract ERC721TL is
Initializer
//////////////////////////////////////////////////////////////////////////*/

/// @dev `tx.origin` is used in the events here as these can be deployed via contract factories and we want to capture the true sender
/// @param name The name of the 721 contract
/// @param symbol The symbol of the 721 contract
/// @param personalization A string to emit as a collection story. Can be ASCII art or something else that is a personalization of the contract.
Expand Down Expand Up @@ -141,17 +140,17 @@ contract ERC721TL is

// story
storyEnabled = enableStory;
emit StoryStatusUpdate(tx.origin, enableStory);
emit StoryStatusUpdate(initOwner, enableStory);

// blocklist and nft delegation registry
blocklistRegistry = IBlockListRegistry(initBlockListRegistry);
emit BlockListRegistryUpdate(tx.origin, address(0), initBlockListRegistry);
emit BlockListRegistryUpdate(initOwner, address(0), initBlockListRegistry);
tlNftDelegationRegistry = ITLNftDelegationRegistry(initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(tx.origin, address(0), initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(initOwner, address(0), initNftDelegationRegistry);

// emit personalization as collection story
if (bytes(personalization).length > 0) {
emit CollectionStory(tx.origin, tx.origin.toHexString(), personalization);
emit CollectionStory(initOwner, initOwner.toHexString(), personalization);
}
}

Expand Down
30 changes: 21 additions & 9 deletions src/erc-721/multi-metadata/CollectorsChoice.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {IERC721TL} from "../IERC721TL.sol";
/// @notice Sovereign ERC-7160 Editions with a metadata lock timer (Collectors Choice) Creator Contract with Story Inscriptions
/// @dev When unpinned, the latest metadata added for a token is returned from `tokenURI` and `tokenURIs`
/// @author transientlabs.xyz
/// @custom:version 3.0.1
/// @custom:version 3.1.0
contract CollectorsChoice is
ERC721Upgradeable,
EIP2981TLUpgradeable,
Expand Down Expand Up @@ -55,11 +55,12 @@ contract CollectorsChoice is
State Variables
//////////////////////////////////////////////////////////////////////////*/

string public constant VERSION = "3.0.1";
string public constant VERSION = "3.1.0";
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
uint256 private _counter; // token ids
bool public storyEnabled;
bool public floatWhenUnpinned;
ITLNftDelegationRegistry public tlNftDelegationRegistry;
IBlockListRegistry public blocklistRegistry;
uint256 public cutoffTime;
Expand Down Expand Up @@ -131,7 +132,6 @@ contract CollectorsChoice is
Initializer
//////////////////////////////////////////////////////////////////////////*/

/// @dev `tx.origin` is used in the events here as these can be deployed via contract factories and we want to capture the true sender
/// @param name The name of the 721 contract
/// @param symbol The symbol of the 721 contract
/// @param personalization A string to emit as a collection story. Can be ASCII art or something else that is a personalization of the contract.
Expand Down Expand Up @@ -164,17 +164,17 @@ contract CollectorsChoice is

// story
storyEnabled = enableStory;
emit StoryStatusUpdate(tx.origin, enableStory);
emit StoryStatusUpdate(initOwner, enableStory);

// blocklist and nft delegation registry
blocklistRegistry = IBlockListRegistry(initBlockListRegistry);
emit BlockListRegistryUpdate(tx.origin, address(0), initBlockListRegistry);
emit BlockListRegistryUpdate(initOwner, address(0), initBlockListRegistry);
tlNftDelegationRegistry = ITLNftDelegationRegistry(initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(tx.origin, address(0), initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(initOwner, address(0), initNftDelegationRegistry);

// emit personalization as collection story
if (bytes(personalization).length > 0) {
emit CollectionStory(tx.origin, tx.origin.toHexString(), personalization);
emit CollectionStory(initOwner, initOwner.toHexString(), personalization);
}
}

Expand Down Expand Up @@ -308,6 +308,14 @@ contract CollectorsChoice is
ERC-7160 Functions
//////////////////////////////////////////////////////////////////////////*/

/// @notice Function to change the unpinned display state
/// @dev floating means that the last item in the tokenUris array will be returned from `tokenUri`
/// @dev if not floating, the first item in the tokenUris array is returned
/// @param float Bool indicating whether to float or not
function setUnpinnedFloatState(bool float) external onlyRoleOrOwner(ADMIN_ROLE) {
floatWhenUnpinned = float;
}

/// @notice Function to add token uris
/// @dev Must be called by contract owner, admin, or approved mint contract
/// @param tokenUris Array of token uris to add
Expand Down Expand Up @@ -336,7 +344,11 @@ contract CollectorsChoice is
// get if pinned
pinned = multiMetadata.pinned;
// set index
index = pinned ? multiMetadata.index : uris.length - 1;
if (pinned) {
index = multiMetadata.index;
} else {
index = floatWhenUnpinned ? uris.length - 1 : 0;
}
}

/// @inheritdoc IERC7160
Expand Down Expand Up @@ -380,7 +392,7 @@ contract CollectorsChoice is
if (multiMetadata.pinned) {
uri = _tokenUris[multiMetadata.index];
} else {
uri = _tokenUris[_tokenUris.length - 1];
uri = floatWhenUnpinned ? _tokenUris[_tokenUris.length - 1] : _tokenUris[0];
}
}

Expand Down
30 changes: 21 additions & 9 deletions src/erc-721/multi-metadata/Doppelganger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {IERC721TL} from "../IERC721TL.sol";
/// @notice Sovereign ERC-7160 Editions (Doppelganger) Creator Contract with Story Inscriptions
/// @dev When unpinned, the latest metadata added for a token is returned from `tokenURI` and `tokenURIs`
/// @author transientlabs.xyz
/// @custom:version 3.0.1
/// @custom:version 3.1.0
contract Doppelganger is
ERC721Upgradeable,
EIP2981TLUpgradeable,
Expand Down Expand Up @@ -55,11 +55,12 @@ contract Doppelganger is
State Variables
//////////////////////////////////////////////////////////////////////////*/

string public constant VERSION = "3.0.1";
string public constant VERSION = "3.1.0";
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
uint256 private _counter; // token ids
bool public storyEnabled;
bool public floatWhenUnpinned;
ITLNftDelegationRegistry public tlNftDelegationRegistry;
IBlockListRegistry public blocklistRegistry;
mapping(uint256 => bool) private _burned; // flag to see if a token is burned or not - needed for burning batch mints
Expand Down Expand Up @@ -117,7 +118,6 @@ contract Doppelganger is
Initializer
//////////////////////////////////////////////////////////////////////////*/

/// @dev `tx.origin` is used in the events here as these can be deployed via contract factories and we want to capture the true sender
/// @param name The name of the 721 contract
/// @param symbol The symbol of the 721 contract
/// @param personalization A string to emit as a collection story. Can be ASCII art or something else that is a personalization of the contract.
Expand Down Expand Up @@ -150,17 +150,17 @@ contract Doppelganger is

// story
storyEnabled = enableStory;
emit StoryStatusUpdate(tx.origin, enableStory);
emit StoryStatusUpdate(initOwner, enableStory);

// blocklist and nft delegation registry
blocklistRegistry = IBlockListRegistry(initBlockListRegistry);
emit BlockListRegistryUpdate(tx.origin, address(0), initBlockListRegistry);
emit BlockListRegistryUpdate(initOwner, address(0), initBlockListRegistry);
tlNftDelegationRegistry = ITLNftDelegationRegistry(initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(tx.origin, address(0), initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(initOwner, address(0), initNftDelegationRegistry);

// emit personalization as collection story
if (bytes(personalization).length > 0) {
emit CollectionStory(tx.origin, tx.origin.toHexString(), personalization);
emit CollectionStory(initOwner, initOwner.toHexString(), personalization);
}
}

Expand Down Expand Up @@ -281,6 +281,14 @@ contract Doppelganger is
ERC-7160 Functions
//////////////////////////////////////////////////////////////////////////*/

/// @notice Function to change the unpinned display state
/// @dev floating means that the last item in the tokenUris array will be returned from `tokenUri`
/// @dev if not floating, the first item in the tokenUris array is returned
/// @param float Bool indicating whether to float or not
function setUnpinnedFloatState(bool float) external onlyRoleOrOwner(ADMIN_ROLE) {
floatWhenUnpinned = float;
}

/// @notice Function to add token uris
/// @dev Must be called by contract owner, admin, or approved mint contract
/// @param tokenUris Array of token uris to add
Expand Down Expand Up @@ -308,7 +316,11 @@ contract Doppelganger is
// get if pinned
pinned = multiMetadata.pinned;
// set index
index = pinned ? multiMetadata.index : uris.length - 1;
if (pinned) {
index = multiMetadata.index;
} else {
index = floatWhenUnpinned ? uris.length - 1 : 0;
}
}

/// @inheritdoc IERC7160
Expand Down Expand Up @@ -350,7 +362,7 @@ contract Doppelganger is
if (multiMetadata.pinned) {
uri = _tokenUris[multiMetadata.index];
} else {
uri = _tokenUris[_tokenUris.length - 1];
uri = floatWhenUnpinned ? _tokenUris[_tokenUris.length - 1] : _tokenUris[0];
}
}

Expand Down
33 changes: 23 additions & 10 deletions src/erc-721/multi-metadata/ERC7160TL.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import {IERC721TL} from "../IERC721TL.sol";

/// @title ERC7160TL.sol
/// @notice Sovereign ERC-7160 Creator Contract with Story Inscriptions
/// @dev When unpinned, the latest metadata added for a token is returned from `tokenURI` and `tokenURIs`
/// @author transientlabs.xyz
/// @custom:version 3.0.1
/// @custom:version 3.1.0
contract ERC7160TL is
ERC721Upgradeable,
EIP2981TLUpgradeable,
Expand Down Expand Up @@ -63,11 +62,12 @@ contract ERC7160TL is
State Variables
//////////////////////////////////////////////////////////////////////////*/

string public constant VERSION = "3.0.1";
string public constant VERSION = "3.1.0";
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
uint256 private _counter; // token ids
bool public storyEnabled;
bool public floatWhenUnpinned;
ITLNftDelegationRegistry public tlNftDelegationRegistry;
IBlockListRegistry public blocklistRegistry;
mapping(uint256 => bool) private _burned; // flag to see if a token is burned or not -- needed for burning batch mints
Expand Down Expand Up @@ -129,7 +129,6 @@ contract ERC7160TL is
Initializer
//////////////////////////////////////////////////////////////////////////*/

/// @dev `tx.origin` is used in the events here as these can be deployed via contract factories and we want to capture the true sender
/// @param name The name of the 721 contract
/// @param symbol The symbol of the 721 contract
/// @param personalization A string to emit as a collection story. Can be ASCII art or something else that is a personalization of the contract.
Expand Down Expand Up @@ -162,17 +161,17 @@ contract ERC7160TL is

// story
storyEnabled = enableStory;
emit StoryStatusUpdate(tx.origin, enableStory);
emit StoryStatusUpdate(initOwner, enableStory);

// blocklist and nft delegation registry
blocklistRegistry = IBlockListRegistry(initBlockListRegistry);
emit BlockListRegistryUpdate(tx.origin, address(0), initBlockListRegistry);
emit BlockListRegistryUpdate(initOwner, address(0), initBlockListRegistry);
tlNftDelegationRegistry = ITLNftDelegationRegistry(initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(tx.origin, address(0), initNftDelegationRegistry);
emit NftDelegationRegistryUpdate(initOwner, address(0), initNftDelegationRegistry);

// emit personalization as collection story
if (bytes(personalization).length > 0) {
emit CollectionStory(tx.origin, tx.origin.toHexString(), personalization);
emit CollectionStory(initOwner, initOwner.toHexString(), personalization);
}
}

Expand Down Expand Up @@ -293,6 +292,15 @@ contract ERC7160TL is
ERC-7160 Functions
//////////////////////////////////////////////////////////////////////////*/

/// @notice Function to change the unpinned display state
/// @dev floating means that the last item in the tokenUris array will be returned from `tokenUri`
/// @dev if not floating, the first item in the tokenUris array is returned
/// @param float Bool indicating whether to float or not
function setUnpinnedFloatState(bool float) external onlyRoleOrOwner(ADMIN_ROLE) {
floatWhenUnpinned = float;
}


/// @notice Function to add token uris
/// @dev Written to take in many token ids and a base uri that contains metadata files with file names matching the index of each token id in the `tokenIds` array (aka folderIndex)
/// @dev No trailing slash on the base uri
Expand Down Expand Up @@ -327,8 +335,13 @@ contract ERC7160TL is
}
// get if pinned
pinned = multiMetadata.pinned;

// set index
index = pinned ? multiMetadata.index : uris.length - 1;
if (pinned) {
index = multiMetadata.index;
} else {
index = floatWhenUnpinned ? uris.length - 1 : 0;
}
}

/// @inheritdoc IERC7160
Expand Down Expand Up @@ -374,7 +387,7 @@ contract ERC7160TL is
uri = _getMultiMetadataUri(multiMetadata, multiMetadata.index - 1);
}
} else {
if (multiMetadata.metadataLocs.length == 0) {
if (multiMetadata.metadataLocs.length == 0 || !floatWhenUnpinned) {
uri = _getMintedMetadataUri(tokenId);
} else {
uri = _getMultiMetadataUri(multiMetadata, multiMetadata.metadataLocs.length - 1);
Expand Down
Loading

0 comments on commit 1b77fb9

Please sign in to comment.