diff --git a/.gitignore b/.gitignore index fb104c5..c9a924e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ cache/ out/ artifacts/ +lib/ # Ignores development broadcast logs !/broadcast @@ -14,4 +15,4 @@ artifacts/ node_modules/ hh-cache -.DS_Store \ No newline at end of file +.DS_Store diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts index d6975f8..9416743 160000 --- a/lib/openzeppelin-contracts +++ b/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit d6975f8e07670f7652e056ee20ab5e4d3f5768c6 +Subproject commit 9416743a1079f35320173b8809e9a28ae8444128 diff --git a/lib/solady b/lib/solady index c795fed..07f093a 160000 --- a/lib/solady +++ b/lib/solady @@ -1 +1 @@ -Subproject commit c795feda7e383fa5370f8d408c53013db3fd2111 +Subproject commit 07f093a69987598d391e953cebb2e53b9a66f093 diff --git a/src/Conclusion.sol b/src/Conclusion.sol index dc21fd4..1b57009 100644 --- a/src/Conclusion.sol +++ b/src/Conclusion.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; +pragma solidity 0.8.13; import "openzeppelin/token/ERC721/ERC721.sol"; import "openzeppelin/access/Ownable.sol"; @@ -12,8 +12,8 @@ contract Conclusion is ERC721, Ownable { error MergeHasOccured(); struct MintInfo { - uint128 blockNum; - uint128 blockdifficulty; + uint128 blockNumber; + uint128 blockDifficulty; } uint256 public lastWorkBlock; @@ -29,17 +29,17 @@ contract Conclusion is ERC721, Ownable { _; } - constructor() ERC721("Conclusion", "CONCLUSION") {} + constructor() ERC721("The Last Work", "CONCLUSION") {} function setRenderer(address renderer) external onlyOwner { conclusionRenderer = renderer; } function mint() external onlyEOA { - if (mintedBlocks[tx.origin] > 0) revert AlreadyMinted(); - if (mergeHasOccured()) revert MergeHasOccured(); + _assetPoW(); - checkProofOfWorkValidAndUpdate(); + if (mintedBlocks[tx.origin] > 0) + revert AlreadyMinted(); uint256 currSupply = totalSupply; @@ -56,13 +56,14 @@ contract Conclusion is ERC721, Ownable { totalSupply = currSupply; } - function checkProofOfWorkValidAndUpdate() public { - if (!mergeHasOccured()) { - lastWorkBlock = block.number; - } + function _assetPoW() internal { + if (isPoS()) + revert MergeHasOccured(); + + lastWorkBlock = block.number; } - function mergeHasOccured() public view returns (bool) { + function isPoS() public view returns (bool) { return block.difficulty > 2**64 || block.difficulty == 0; } @@ -73,11 +74,11 @@ contract Conclusion is ERC721, Ownable { override returns (string memory) { - if (!_exists(_tokenId)) revert TokenDoesNotExist(); + if (!_exists(_tokenId)) + revert TokenDoesNotExist(); - if (conclusionRenderer == address(0)) { + if (conclusionRenderer == address(0)) return ""; - } MintInfo memory info = tokenToBlockNum[_tokenId]; diff --git a/src/Genesis.sol b/src/Genesis.sol index cda5937..6d4c0c9 100644 --- a/src/Genesis.sol +++ b/src/Genesis.sol @@ -10,10 +10,13 @@ contract Genesis is ERC721, Ownable { error AlreadyMinted(); error TokenDoesNotExist(); error MergeHasNotOccured(); + error TooLate(); + + uint256 immutable MAX_MINT_DISTANCE = 100; struct MintInfo { - uint128 blockNum; - uint128 blockdifficulty; + uint128 blockNumber; + uint128 blockDifficulty; } uint256 public genesisMergeBlock; @@ -29,17 +32,20 @@ contract Genesis is ERC721, Ownable { _; } - constructor() ERC721("Genesis", "GENESIS") {} + constructor() ERC721("New Genesis", "GENESIS") {} function setRenderer(address renderer) external onlyOwner { genesisRenderer = renderer; } - function mint() external onlyEOA { - if (mintedBlocks[tx.origin] > 0) revert AlreadyMinted(); - if (!mergeHasOccured()) revert MergeHasNotOccured(); + function mint() external onlyEOA { + assertPos(); + + if (mintedBlocks[tx.origin] > 0) + revert AlreadyMinted(); - checkForMergeAndUpdate(); + if (block.number - genesisMergeBlock > MAX_MINT_DISTANCE) + revert TooLate(); uint256 currSupply = totalSupply; @@ -56,13 +62,15 @@ contract Genesis is ERC721, Ownable { totalSupply = currSupply; } - function checkForMergeAndUpdate() public { - if (genesisMergeBlock == 0 && mergeHasOccured()) { + function assertPoS() public { + if (!isPoS()) + revert MergeHasNotOccured(); + + if (genesisMergeBlock == 0) genesisMergeBlock = block.number; - } } - function mergeHasOccured() public view returns (bool) { + function isPoS() public view returns (bool) { return block.difficulty > 2**64 || block.difficulty == 0; } @@ -73,19 +81,19 @@ contract Genesis is ERC721, Ownable { override returns (string memory) { - if (!_exists(_tokenId)) revert TokenDoesNotExist(); + if (!_exists(_tokenId)) + revert TokenDoesNotExist(); - if (genesisRenderer == address(0)) { + if (genesisRenderer == address(0)) return ""; - } MintInfo memory info = tokenToBlockNum[_tokenId]; return IGenesisRenderer(genesisRenderer).tokenURI( _tokenId, - info.blockNum, - info.blockdifficulty + info.blockNumber, + genesisMergeBlock ); } } diff --git a/test/Conclusion.t.sol b/test/Conclusion.t.sol index f0eccc2..fab540d 100644 --- a/test/Conclusion.t.sol +++ b/test/Conclusion.t.sol @@ -1,13 +1,26 @@ -// // SPDX-License-Identifier: UNLICENSED -// pragma solidity ^0.8.13; +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.13; -// import "forge-std/Test.sol"; -// import "../src/Conclusion.sol"; +import "forge-std/Test.sol"; +import "../src/Conclusion.sol"; -// contract ConclusionTest is Test { -// function setUp() public { -// } +contract ConclusionTest is Test { + Conclusion public c; + function setUp() public { + c = new Conclusion(); + vm.difficulty(2**25); + } -// } + function test_mintContract() public { + vm.expectRevert("only EOA"); + c.mint(); + } -// didnt have time to write tests T_T , but it was reviewed by some big brains. + function test_mint() public { + vm.prank(0x4C9ACeE7Ba4d5AFD8408D0c68591e2ABB01A3ec9, 0x4C9ACeE7Ba4d5AFD8408D0c68591e2ABB01A3ec9); + c.mint(); + } + + function test_idk() public { + } +} diff --git a/test/Genesis.t.sol b/test/Genesis.t.sol new file mode 100644 index 0000000..fa940f4 --- /dev/null +++ b/test/Genesis.t.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.13; + +import "forge-std/Test.sol"; +import "../src/Genesis.sol"; + +contract GenesisTest is Test { + Genesis public g; + function setUp() public { + g = new Genesis(); + vm.difficulty(2**255); + } + + function mintContract() public { + vm.expectRevert("only EOA"); + g.mint(); + } + + function test_mint() public { + vm.prank(0x4C9ACeE7Ba4d5AFD8408D0c68591e2ABB01A3ec9, 0x4C9ACeE7Ba4d5AFD8408D0c68591e2ABB01A3ec9); + g.mint(); + } + + function test_idk() public { + } +}