Skip to content

Commit

Permalink
Feat/split and merge (#1185)
Browse files Browse the repository at this point in the history
* Add split and merge functionality to plasmic and add component logic.
  • Loading branch information
Jipperism authored Nov 21, 2023
1 parent dbdb083 commit a6c3b8f
Show file tree
Hide file tree
Showing 19 changed files with 376 additions and 125 deletions.
4 changes: 2 additions & 2 deletions contracts/test/mock/MockERC1155.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { ERC1155 } from "solmate/src/tokens/ERC1155.sol";
import {ERC1155} from "solmate/src/tokens/ERC1155.sol";

// LooksRare unopinionated libraries
import { IERC2981 } from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC2981.sol";
import {IERC2981} from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC2981.sol";

contract MockERC1155 is ERC1155 {
function batchMint(address to, uint256[] memory tokenIds, uint256[] memory amounts) public {
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockERC1155SupportsNoInterface.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { MockERC1155 } from "./MockERC1155.sol";
import {MockERC1155} from "./MockERC1155.sol";

contract MockERC1155SupportsNoInterface is MockERC1155 {
function supportsInterface(bytes4) public view virtual override returns (bool) {
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockERC1155WithoutAnyBalanceOf.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

/**
* @dev This contract has to inherit from OZ instead of Solmate because
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockERC1155WithoutBalanceOfBatch.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { MockERC1155 } from "./MockERC1155.sol";
import {MockERC1155} from "./MockERC1155.sol";

contract MockERC1155WithoutBalanceOfBatch is MockERC1155 {
function balanceOfBatch(address[] calldata, uint256[] calldata) public pure override returns (uint256[] memory) {
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockERC1155WithoutIsApprovedForAll.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

/**
* @dev This contract has to inherit from OZ instead of Solmate because
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockERC20.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { ERC20 } from "solmate/src/tokens/ERC20.sol";
import {ERC20} from "solmate/src/tokens/ERC20.sol";

contract MockERC20 is ERC20("MockERC20", "MockERC20", 18) {
function mint(address to, uint256 amount) public {
Expand Down
4 changes: 2 additions & 2 deletions contracts/test/mock/MockERC721.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { ERC721 } from "solmate/src/tokens/ERC721.sol";
import { IERC165 } from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC165.sol";
import {ERC721} from "solmate/src/tokens/ERC721.sol";
import {IERC165} from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC165.sol";

contract MockERC721 is ERC721("MockERC721", "MockERC721") {
function mint(address to, uint256 tokenId) public {
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockERC721SupportsNoInterface.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.7;

import { MockERC721 } from "./MockERC721.sol";
import {MockERC721} from "./MockERC721.sol";

contract MockERC721SupportsNoInterface is MockERC721 {
function supportsInterface(bytes4) public view virtual override returns (bool) {
Expand Down
24 changes: 12 additions & 12 deletions contracts/test/mock/MockERC721WithRoyalties.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import { IERC165, IERC2981 } from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC2981.sol";
import { MockERC721 } from "./MockERC721.sol";
import {IERC165, IERC2981} from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC2981.sol";
import {MockERC721} from "./MockERC721.sol";

// Constants
import { ONE_HUNDRED_PERCENT_IN_BP } from "@hypercerts/marketplace/constants/NumericConstants.sol";
import {ONE_HUNDRED_PERCENT_IN_BP} from "@hypercerts/marketplace/constants/NumericConstants.sol";

/**
* @dev This contract allows adding a royalty basis points higher than 10,000, which
Expand All @@ -25,19 +25,19 @@ contract MockERC721WithRoyalties is MockERC721, IERC2981 {
DEFAULT_ROYALTY_FEE = _royaltyFee;
}

function addCustomRoyaltyInformationForTokenId(
uint256 tokenId,
address royaltyRecipient,
uint256 royaltyFee
) external {
function addCustomRoyaltyInformationForTokenId(uint256 tokenId, address royaltyRecipient, uint256 royaltyFee)
external
{
_royaltyRecipientForTokenId[tokenId] = royaltyRecipient;
_royaltyFeeForTokenId[tokenId] = royaltyFee;
}

function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) external view override returns (address royaltyRecipient, uint256 royaltyAmount) {
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
override
returns (address royaltyRecipient, uint256 royaltyAmount)
{
royaltyRecipient = _royaltyRecipientForTokenId[tokenId] == address(0)
? DEFAULT_ROYALTY_RECIPIENT
: _royaltyRecipientForTokenId[tokenId];
Expand Down
22 changes: 10 additions & 12 deletions contracts/test/mock/MockRoyaltyFeeRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
pragma solidity 0.8.17;

// LooksRare unopinionated libraries
import { OwnableTwoSteps } from "@looksrare/contracts-libs/contracts/OwnableTwoSteps.sol";
import {OwnableTwoSteps} from "@looksrare/contracts-libs/contracts/OwnableTwoSteps.sol";

// Royalty Fee Registry interface
import { IRoyaltyFeeRegistry } from "@hypercerts/marketplace/interfaces/IRoyaltyFeeRegistry.sol";
import {IRoyaltyFeeRegistry} from "@hypercerts/marketplace/interfaces/IRoyaltyFeeRegistry.sol";

// Constants
import { ONE_HUNDRED_PERCENT_IN_BP } from "@hypercerts/marketplace/constants/NumericConstants.sol";
import {ONE_HUNDRED_PERCENT_IN_BP} from "@hypercerts/marketplace/constants/NumericConstants.sol";

/**
* @title MockRoyaltyFeeRegistry
Expand Down Expand Up @@ -36,7 +36,7 @@ contract MockRoyaltyFeeRegistry is IRoyaltyFeeRegistry, OwnableTwoSteps {
* @param _royaltyFeeLimit new royalty fee limit (500 = 5%, 1,000 = 10%)
*/
constructor(address _owner, uint256 _royaltyFeeLimit) OwnableTwoSteps(_owner) {
require(_royaltyFeeLimit <= 9_500, "Owner: Royalty fee limit too high");
require(_royaltyFeeLimit <= 9500, "Owner: Royalty fee limit too high");
royaltyFeeLimit = _royaltyFeeLimit;
}

Expand All @@ -45,7 +45,7 @@ contract MockRoyaltyFeeRegistry is IRoyaltyFeeRegistry, OwnableTwoSteps {
* @param _royaltyFeeLimit new royalty fee limit (500 = 5%, 1,000 = 10%)
*/
function updateRoyaltyFeeLimit(uint256 _royaltyFeeLimit) external onlyOwner {
require(_royaltyFeeLimit <= 9_500, "Owner: Royalty fee limit too high");
require(_royaltyFeeLimit <= 9500, "Owner: Royalty fee limit too high");
royaltyFeeLimit = _royaltyFeeLimit;

emit NewRoyaltyFeeLimit(_royaltyFeeLimit);
Expand All @@ -58,14 +58,12 @@ contract MockRoyaltyFeeRegistry is IRoyaltyFeeRegistry, OwnableTwoSteps {
* @param receiver receiver for the royalty fee
* @param fee fee (500 = 5%, 1,000 = 10%)
*/
function updateRoyaltyInfoForCollection(
address collection,
address setter,
address receiver,
uint256 fee
) external onlyOwner {
function updateRoyaltyInfoForCollection(address collection, address setter, address receiver, uint256 fee)
external
onlyOwner
{
require(fee <= royaltyFeeLimit, "Registry: Royalty fee too high");
_royaltyFeeInfoCollection[collection] = FeeInfo({ setter: setter, receiver: receiver, fee: fee });
_royaltyFeeInfoCollection[collection] = FeeInfo({setter: setter, receiver: receiver, fee: fee});

emit RoyaltyFeeUpdate(collection, setter, receiver, fee);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/mock/MockSmartWallet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract MockSmartWallet {
}

function execute(address dest, uint256 value, bytes calldata calldata_) public onlyOwner {
(bool success, bytes memory result) = dest.call{ value: value }(calldata_);
(bool success, bytes memory result) = dest.call{value: value}(calldata_);

if (!success) {
assembly {
Expand Down
90 changes: 86 additions & 4 deletions frontend/components/merge-all-claim-fractions-button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import React from "react";
import { Button } from "@mui/material";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from "@mui/material";
import { useMergeFractionUnits } from "../hooks/mergeFractionUnits";
import { toast } from "react-toastify";
import { useHypercertClient } from "../hooks/hypercerts-client";
import { useAccountLowerCase } from "../hooks/account";

interface Props {
claimId: string;
Expand All @@ -14,13 +25,84 @@ export function MergeAllClaimFractionsButton({
className,
disabled,
}: Props) {
const [open, setOpen] = React.useState(false);
const { write, readOnly, txPending } = useMergeFractionUnits({});
const { client, isLoading } = useHypercertClient();
const { address } = useAccountLowerCase();

const onClick = async () => {
console.log("Merging all claim fractions", claimId);
setOpen(false);
if (readOnly) {
toast("Please connect your wallet to merge all claim fractions");
return;
}

if (isLoading) {
toast("Please wait for the client to be ready");
return;
}

if (!client) {
toast("Please connect your wallet to merge all claim fractions");
return;
}

if (!address) {
toast("Please connect your wallet to merge all claim fractions");
return;
}

const fractionUnits = await client.indexer.fractionsByClaim(claimId);
console.log("Fraction units", fractionUnits);

const myFractions = fractionUnits.claimTokens.filter(
(fraction) => fraction.owner === address,
);

console.log("address", address);
console.log("My fractions", myFractions);

if (!myFractions.length) {
toast("No fractions to merge");
return;
}

await write(myFractions.map((fraction) => fraction.tokenID));
};

const isDisabled = disabled || txPending || readOnly || isLoading;

return (
<Button disabled={disabled} className={className} onClick={onClick}>
{text}
</Button>
<>
<Button
disabled={isDisabled}
className={className}
onClick={() => setOpen(true)}
>
{text}
</Button>
<Dialog
open={open}
onClose={() => setOpen(false)}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
{"Merge all your fractions for this hypercert?"}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
This action cannot be reversed
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)}>Disagree</Button>
<Button onClick={onClick} autoFocus>
Agree
</Button>
</DialogActions>
</Dialog>
</>
);
}
Loading

0 comments on commit a6c3b8f

Please sign in to comment.