-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8eb8617
commit 26e3bd9
Showing
5 changed files
with
427 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.19; | ||
|
||
import {ERC721Items} from "@0xsequence/contracts-library/tokens/ERC721/presets/items/ERC721Items.sol"; | ||
import {IERC721Soulbound, IERC721SoulboundFunctions} from "@0xsequence/contracts-library/tokens/ERC721/presets/soulbound/IERC721Soulbound.sol"; | ||
|
||
/** | ||
* An implementation of ERC-721 that prevents transfers. | ||
*/ | ||
contract ERC721Soulbound is ERC721Items, IERC721Soulbound { | ||
|
||
bytes32 public constant TRANSFER_ADMIN_ROLE = keccak256("TRANSFER_ADMIN_ROLE"); | ||
|
||
bool internal _transferLocked; | ||
|
||
constructor() ERC721Items() {} | ||
|
||
/// @inheritdoc ERC721Items | ||
function initialize( | ||
address owner, | ||
string memory tokenName, | ||
string memory tokenSymbol, | ||
string memory tokenBaseURI, | ||
string memory tokenContractURI, | ||
address royaltyReceiver, | ||
uint96 royaltyFeeNumerator | ||
) public virtual override { | ||
_transferLocked = true; | ||
_grantRole(TRANSFER_ADMIN_ROLE, owner); | ||
super.initialize(owner, tokenName, tokenSymbol, tokenBaseURI, tokenContractURI, royaltyReceiver, royaltyFeeNumerator); | ||
} | ||
|
||
/// @inheritdoc IERC721SoulboundFunctions | ||
function setTransferLocked(bool locked) external override onlyRole(TRANSFER_ADMIN_ROLE) { | ||
_transferLocked = locked; | ||
} | ||
|
||
/// @inheritdoc IERC721SoulboundFunctions | ||
function getTransferLocked() external view override returns (bool) { | ||
return _transferLocked; | ||
} | ||
|
||
function _beforeTokenTransfers( | ||
address from, | ||
address to, | ||
uint256 startTokenId, | ||
uint256 quantity | ||
) internal virtual override { | ||
// Mint transactions allowed | ||
if (_transferLocked && from != address(0)) { | ||
revert TransfersLocked(); | ||
} | ||
super._beforeTokenTransfers(from, to, startTokenId, quantity); | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
src/tokens/ERC721/presets/soulbound/ERC721SoulboundFactory.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.19; | ||
|
||
import {IERC721SoulboundFactory, IERC721SoulboundFactoryFunctions} from | ||
"@0xsequence/contracts-library/tokens/ERC721/presets/soulbound/IERC721SoulboundFactory.sol"; | ||
import {ERC721Soulbound} from "@0xsequence/contracts-library/tokens/ERC721/presets/soulbound/ERC721Soulbound.sol"; | ||
import {SequenceProxyFactory} from "@0xsequence/contracts-library/proxies/SequenceProxyFactory.sol"; | ||
|
||
/** | ||
* Deployer of ERC-721 Soulbound proxies. | ||
*/ | ||
contract ERC721SoulboundFactory is IERC721SoulboundFactory, SequenceProxyFactory { | ||
/** | ||
* Creates an ERC-721 Soulbound Factory. | ||
* @param factoryOwner The owner of the ERC-721 Soulbound Factory | ||
*/ | ||
constructor(address factoryOwner) { | ||
ERC721Soulbound impl = new ERC721Soulbound(); | ||
SequenceProxyFactory._initialize(address(impl), factoryOwner); | ||
} | ||
|
||
/// @inheritdoc IERC721SoulboundFactoryFunctions | ||
function deploy( | ||
address proxyOwner, | ||
address tokenOwner, | ||
string memory name, | ||
string memory symbol, | ||
string memory baseURI, | ||
string memory contractURI, | ||
address royaltyReceiver, | ||
uint96 royaltyFeeNumerator | ||
) | ||
external | ||
returns (address proxyAddr) | ||
{ | ||
bytes32 salt = | ||
keccak256(abi.encode(tokenOwner, name, symbol, baseURI, contractURI, royaltyReceiver, royaltyFeeNumerator)); | ||
proxyAddr = _createProxy(salt, proxyOwner, ""); | ||
ERC721Soulbound(proxyAddr).initialize(tokenOwner, name, symbol, baseURI, contractURI, royaltyReceiver, royaltyFeeNumerator); | ||
emit ERC721SoulboundDeployed(proxyAddr); | ||
return proxyAddr; | ||
} | ||
|
||
/// @inheritdoc IERC721SoulboundFactoryFunctions | ||
function determineAddress( | ||
address proxyOwner, | ||
address tokenOwner, | ||
string memory name, | ||
string memory symbol, | ||
string memory baseURI, | ||
string memory contractURI, | ||
address royaltyReceiver, | ||
uint96 royaltyFeeNumerator | ||
) external view returns (address proxyAddr) | ||
{ | ||
bytes32 salt = | ||
keccak256(abi.encode(tokenOwner, name, symbol, baseURI, contractURI, royaltyReceiver, royaltyFeeNumerator)); | ||
return _computeProxyAddress(salt, proxyOwner, ""); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.19; | ||
|
||
interface IERC721SoulboundFunctions { | ||
/** | ||
* Sets the transfer lock. | ||
* @param locked Whether or not transfers are locked. | ||
*/ | ||
function setTransferLocked(bool locked) external; | ||
|
||
/** | ||
* Gets the transfer lock. | ||
* @return Whether or not transfers are locked. | ||
*/ | ||
function getTransferLocked() external view returns (bool); | ||
} | ||
|
||
interface IERC721SoulboundSignals { | ||
/** | ||
* Transfers locked. | ||
*/ | ||
error TransfersLocked(); | ||
} | ||
|
||
interface IERC721Soulbound is IERC721SoulboundFunctions, IERC721SoulboundSignals {} |
64 changes: 64 additions & 0 deletions
64
src/tokens/ERC721/presets/soulbound/IERC721SoulboundFactory.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.19; | ||
|
||
interface IERC721SoulboundFactoryFunctions { | ||
/** | ||
* Creates an ERC-721 Soulbound proxy. | ||
* @param proxyOwner The owner of the ERC-721 Soulbound proxy | ||
* @param tokenOwner The owner of the ERC-721 Soulbound implementation | ||
* @param name The name of the ERC-721 Soulbound proxy | ||
* @param symbol The symbol of the ERC-721 Soulbound proxy | ||
* @param baseURI The base URI of the ERC-721 Soulbound proxy | ||
* @param contractURI The contract URI of the ERC-721 Soulbound proxy | ||
* @param royaltyReceiver Address of who should be sent the royalty payment | ||
* @param royaltyFeeNumerator The royalty fee numerator in basis points (e.g. 15% would be 1500) | ||
* @return proxyAddr The address of the ERC-721 Soulbound Proxy | ||
*/ | ||
function deploy( | ||
address proxyOwner, | ||
address tokenOwner, | ||
string memory name, | ||
string memory symbol, | ||
string memory baseURI, | ||
string memory contractURI, | ||
address royaltyReceiver, | ||
uint96 royaltyFeeNumerator | ||
) | ||
external | ||
returns (address proxyAddr); | ||
|
||
/** | ||
* Computes the address of a proxy instance. | ||
* @param proxyOwner The owner of the ERC-721 Soulbound proxy | ||
* @param tokenOwner The owner of the ERC-721 Soulbound implementation | ||
* @param name The name of the ERC-721 Soulbound proxy | ||
* @param symbol The symbol of the ERC-721 Soulbound proxy | ||
* @param baseURI The base URI of the ERC-721 Soulbound proxy | ||
* @param contractURI The contract URI of the ERC-721 Soulbound proxy | ||
* @param royaltyReceiver Address of who should be sent the royalty payment | ||
* @param royaltyFeeNumerator The royalty fee numerator in basis points (e.g. 15% would be 1500) | ||
* @return proxyAddr The address of the ERC-721 Soulbound Proxy | ||
*/ | ||
function determineAddress( | ||
address proxyOwner, | ||
address tokenOwner, | ||
string memory name, | ||
string memory symbol, | ||
string memory baseURI, | ||
string memory contractURI, | ||
address royaltyReceiver, | ||
uint96 royaltyFeeNumerator | ||
) | ||
external | ||
returns (address proxyAddr); | ||
} | ||
|
||
interface IERC721SoulboundFactorySignals { | ||
/** | ||
* Event emitted when a new ERC-721 Soulbound proxy contract is deployed. | ||
* @param proxyAddr The address of the deployed proxy. | ||
*/ | ||
event ERC721SoulboundDeployed(address proxyAddr); | ||
} | ||
|
||
interface IERC721SoulboundFactory is IERC721SoulboundFactoryFunctions, IERC721SoulboundFactorySignals {} |
Oops, something went wrong.