-
Notifications
You must be signed in to change notification settings - Fork 1
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
Showing
10 changed files
with
151 additions
and
55 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 |
---|---|---|
|
@@ -14,3 +14,4 @@ docs/ | |
.env | ||
|
||
/dependencies | ||
/.vscode |
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
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 |
---|---|---|
@@ -1,2 +1,3 @@ | ||
forge-std=dependencies/forge-std-1.8.2/src | ||
forge-std=dependencies/forge-std-1.9.1/src | ||
@openzeppelin/contracts=dependencies/@openzeppelin-contracts-5.0.2 | ||
@openzeppelin/contracts-upgradeable=dependencies/@openzeppelin-contracts-upgradeable-5.0.2 |
This file was deleted.
Oops, something went wrong.
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
This file was deleted.
Oops, something went wrong.
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,35 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.24; | ||
|
||
import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; | ||
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; | ||
|
||
contract Product is Initializable, ERC721Upgradeable, OwnableUpgradeable { | ||
string public baseURI; | ||
|
||
constructor() { | ||
_disableInitializers(); | ||
} | ||
|
||
function initialize(address initialOwner, string calldata name, string calldata symbol) public initializer { | ||
__ERC721_init(name, symbol); | ||
__Ownable_init(initialOwner); | ||
} | ||
|
||
function setBaseURI(string calldata baseURI_) external onlyOwner { | ||
baseURI = baseURI_; | ||
} | ||
|
||
function _baseURI() internal view override returns (string memory) { | ||
return baseURI; | ||
} | ||
|
||
function mint(address to, uint256 tokenId) public onlyOwner { | ||
_mint(to, tokenId); | ||
} | ||
|
||
function safeMint(address to, uint256 tokenId) public onlyOwner { | ||
_safeMint(to, tokenId); | ||
} | ||
} |
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,38 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.24; | ||
|
||
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; | ||
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import {Product} from "./Product.sol"; | ||
|
||
contract ProductFactory is Ownable { | ||
address public product_template; | ||
|
||
constructor(address product_template_) Ownable(msg.sender) { | ||
setProgramTemplate(product_template_); | ||
} | ||
|
||
function setProgramTemplate(address product_template_) public onlyOwner { | ||
requireIsContract(product_template_); | ||
product_template = product_template_; | ||
} | ||
|
||
function requireIsContract(address contract_address) internal view { | ||
uint256 code_size; | ||
assembly { | ||
code_size := extcodesize(contract_address) | ||
} | ||
require(code_size > 0); | ||
} | ||
|
||
function createProduct(string calldata name, string calldata symbol) external returns (Product product) { | ||
address product_address = _createProduct(product_template, msg.sender, name); | ||
product = Product(product_address); | ||
product.initialize(msg.sender, name, symbol); | ||
} | ||
|
||
function _createProduct(address implementation, address vendor, string calldata name) internal returns (address) { | ||
bytes32 salt = keccak256(abi.encodePacked("DePHY_ID", vendor, name)); | ||
return Clones.cloneDeterministic(implementation, salt); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
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: MIT | ||
pragma solidity ^0.8.24; | ||
|
||
import {Test, console} from "forge-std/Test.sol"; | ||
import {Product} from "../src/Product.sol"; | ||
import {ProductFactory} from "../src/ProductFactory.sol"; | ||
|
||
contract ProductFactoryTest is Test { | ||
ProductFactory product_factory; | ||
Product template_product; | ||
Product test_product; | ||
|
||
address factory_owner; | ||
address product_owner; | ||
|
||
function setUp() public { | ||
factory_owner = vm.createWallet(0x42).addr; | ||
|
||
template_product = new Product(); | ||
|
||
vm.prank(factory_owner); | ||
product_factory = new ProductFactory(address(template_product)); | ||
assertEq(product_factory.owner(), factory_owner); | ||
|
||
product_owner = vm.createWallet(0x99).addr; | ||
vm.prank(product_owner); | ||
test_product = product_factory.createProduct("Test Product", "TEST"); | ||
} | ||
|
||
function test_product_template() public { | ||
assertEq(product_factory.product_template(), address(template_product)); | ||
|
||
Product product2 = new Product(); | ||
vm.prank(factory_owner); | ||
product_factory.setProgramTemplate(address(product2)); | ||
assertEq(product_factory.product_template(), address(product2)); | ||
} | ||
|
||
function test_create_product() public { | ||
test_product = product_factory.createProduct("Test Product", "TEST"); | ||
|
||
assertEq(test_product.name(), "Test Product"); | ||
assertEq(test_product.symbol(), "TEST"); | ||
} | ||
|
||
function test_mint_product() public { | ||
assertEq(test_product.owner(), product_owner); | ||
|
||
vm.prank(product_owner); | ||
test_product.mint(msg.sender, 2024); | ||
assertEq(test_product.ownerOf(2024), msg.sender); | ||
|
||
assertEq(test_product.tokenURI(2024), ""); | ||
vm.prank(product_owner); | ||
test_product.setBaseURI("https://example.com/"); | ||
assertEq(test_product.tokenURI(2024), "https://example.com/2024"); | ||
} | ||
|
||
function testFuzz_mint_product(address tokenOwner, uint256 tokenId) public { | ||
vm.prank(product_owner); | ||
test_product.mint(tokenOwner, tokenId); | ||
assertEq(test_product.ownerOf(tokenId), tokenOwner); | ||
} | ||
} |