Skip to content

Commit 5547642

Browse files
committed
drops stoneage Synthesizer
extracts IIPToken interface to be reused on Tokenizer and Permissioner fixes linearization of dependencies on IPToken Signed-off-by: Stefan Adolf <[email protected]>
1 parent e31c28b commit 5547642

14 files changed

+220
-150
lines changed

script/dev/Synthesizer.s.sol

Lines changed: 0 additions & 100 deletions
This file was deleted.

script/dev/Tokenizer.s.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import "forge-std/Script.sol";
55
import "forge-std/console.sol";
66
import { IPNFT } from "../../src/IPNFT.sol";
77
import { Tokenizer } from "../../src/Tokenizer.sol";
8-
import { Metadata, IPToken } from "../../src/IPToken.sol";
8+
import { Metadata } from "../../src/IIPToken.sol";
9+
import { IPToken } from "../../src/IPToken.sol";
10+
911
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
1012
import { IPermissioner, TermsAcceptedPermissioner } from "../../src/Permissioner.sol";
1113
import { CommonScript } from "./Common.sol";
@@ -60,3 +62,4 @@ contract FixtureTokenizer is CommonScript {
6062
console.log("IPTS_ADDRESS=%s", address(tokenContract));
6163
}
6264
}
65+

src/IIPToken.sol

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8;
3+
4+
struct Metadata {
5+
uint256 ipnftId;
6+
address originalOwner;
7+
string agreementCid;
8+
}
9+
10+
interface IIPToken {
11+
/// @notice the amount of tokens that ever have been issued (not necessarily == supply)
12+
function totalIssued() external view returns (uint256);
13+
function balanceOf(address account) external view returns (uint256);
14+
function metadata() external view returns (Metadata memory);
15+
function issue(address, uint256) external;
16+
function cap() external;
17+
function uri() external view returns (string memory);
18+
}

src/IPToken.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.18;
33

4+
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
45
import { ERC20BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
56
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
67
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
78
import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol";
89
import { Tokenizer, MustControlIpnft } from "./Tokenizer.sol";
910
import { IControlIPTs } from "./IControlIPTs.sol";
10-
11-
struct Metadata {
12-
uint256 ipnftId;
13-
address originalOwner;
14-
string agreementCid;
15-
}
11+
import { IIPToken, Metadata } from "./IIPToken.sol";
1612

1713
error TokenCapped();
1814

@@ -24,7 +20,7 @@ error TokenCapped();
2420
* The owner can increase the token supply as long as it's not explicitly capped.
2521
* @dev formerly known as "molecules"
2622
*/
27-
contract IPToken is ERC20BurnableUpgradeable, OwnableUpgradeable {
23+
contract IPToken is IIPToken, ERC20Upgradeable, ERC20BurnableUpgradeable, OwnableUpgradeable {
2824
event Capped(uint256 atSupply);
2925

3026
/// @notice the amount of tokens that ever have been issued (not necessarily == supply)
@@ -59,6 +55,10 @@ contract IPToken is ERC20BurnableUpgradeable, OwnableUpgradeable {
5955
return _metadata;
6056
}
6157

58+
function balanceOf(address account) public view override(ERC20Upgradeable, IIPToken) returns (uint256) {
59+
return ERC20Upgradeable.balanceOf(account);
60+
}
61+
6262
/**
6363
* @notice the supply of IP Tokens is controlled by the tokenizer contract.
6464
* @param receiver address

src/Permissioner.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pragma solidity 0.8.18;
44
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
55
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
66
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
7-
import { IPToken, Metadata } from "./IPToken.sol";
7+
import { IIPToken, Metadata } from "./IIPToken.sol";
88

99
error InvalidSignature();
1010
error Denied();
@@ -16,17 +16,17 @@ interface IPermissioner {
1616
* @param _for address
1717
* @param data bytes
1818
*/
19-
function accept(IPToken tokenContract, address _for, bytes calldata data) external;
19+
function accept(IIPToken tokenContract, address _for, bytes calldata data) external;
2020
}
2121

2222
contract BlindPermissioner is IPermissioner {
23-
function accept(IPToken tokenContract, address _for, bytes calldata data) external {
23+
function accept(IIPToken tokenContract, address _for, bytes calldata data) external {
2424
//empty
2525
}
2626
}
2727

2828
contract ForbidAllPermissioner is IPermissioner {
29-
function accept(IPToken, address, bytes calldata) external pure {
29+
function accept(IIPToken, address, bytes calldata) external pure {
3030
revert Denied();
3131
}
3232
}
@@ -44,7 +44,7 @@ contract TermsAcceptedPermissioner is IPermissioner {
4444
* @param _for address the account that has created `signature`
4545
* @param signature bytes encoded signature, for eip155: `abi.encodePacked(r, s, v)`
4646
*/
47-
function accept(IPToken tokenContract, address _for, bytes calldata signature) external {
47+
function accept(IIPToken tokenContract, address _for, bytes calldata signature) external {
4848
if (!isValidSignature(tokenContract, _for, signature)) {
4949
revert InvalidSignature();
5050
}
@@ -55,7 +55,7 @@ contract TermsAcceptedPermissioner is IPermissioner {
5555
* @notice checks whether `signer`'s `signature` of `specificTermsV1` on `tokenContract.metadata.ipnftId` is valid
5656
* @param tokenContract IPToken
5757
*/
58-
function isValidSignature(IPToken tokenContract, address signer, bytes calldata signature) public view returns (bool) {
58+
function isValidSignature(IIPToken tokenContract, address signer, bytes calldata signature) public view returns (bool) {
5959
bytes32 termsHash = ECDSA.toEthSignedMessageHash(bytes(specificTermsV1(tokenContract)));
6060
return SignatureChecker.isValidSignatureNow(signer, termsHash, signature);
6161
}
@@ -78,7 +78,7 @@ contract TermsAcceptedPermissioner is IPermissioner {
7878
* @notice this yields the message text that claimers must present to proof they have accepted all terms
7979
* @param tokenContract IPToken
8080
*/
81-
function specificTermsV1(IPToken tokenContract) public view returns (string memory) {
81+
function specificTermsV1(IIPToken tokenContract) public view returns (string memory) {
8282
return (specificTermsV1(tokenContract.metadata()));
8383
}
8484
}

src/SalesShareDistributor.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/O
88
import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
99
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
1010
import { IPNFT } from "./IPNFT.sol";
11-
import { IPToken, Metadata } from "./IPToken.sol";
11+
import { Metadata } from "./IIPToken.sol";
12+
import { IPToken } from "./IPToken.sol";
1213
import { Tokenizer, MustControlIpnft } from "./Tokenizer.sol";
1314
import { SchmackoSwap, ListingState } from "./SchmackoSwap.sol";
1415
import { IPermissioner, TermsAcceptedPermissioner } from "./Permissioner.sol";
@@ -133,7 +134,7 @@ contract SalesShareDistributor is UUPSUpgradeable, OwnableUpgradeable, Reentranc
133134
* Requires the originalOwner to behave honestly / in favor of the IPT holders
134135
* Requires the caller to have approved `paidPrice` of `paymentToken` to this contract
135136
*
136-
* @param tokenContract IPToken the IPToken token contract
137+
* @param tokenContract IIPToken the IPToken token contract
137138
* @param paymentToken IERC20 the payment token contract address
138139
* @param paidPrice uint256 the price the NFT has been sold for
139140
* @param permissioner IPermissioner the permissioner that permits claims

src/Tokenizer.sol

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/O
66
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
77
import { Clones } from "@openzeppelin/contracts/proxy/Clones.sol";
88
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
9-
import { IPToken, Metadata as TokenMetadata } from "./IPToken.sol";
9+
import { IIPToken, Metadata as TokenMetadata } from "./IIPToken.sol";
10+
import { IPToken } from "./IPToken.sol";
1011
import { WrappedIPToken } from "./WrappedIPToken.sol";
1112

1213
import { IPermissioner } from "./Permissioner.sol";
@@ -33,14 +34,14 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable, IControlIPTs {
3334
string symbol
3435
);
3536

36-
event TokenWrapped(IERC20Metadata tokenContract, IPToken wrappedIpt);
37-
event IPTokenImplementationUpdated(IPToken indexed old, IPToken indexed _new);
37+
event TokenWrapped(IERC20Metadata tokenContract, IIPToken wrappedIpt);
38+
event IPTokenImplementationUpdated(IIPToken indexed old, IIPToken indexed _new);
3839
event PermissionerUpdated(IPermissioner indexed old, IPermissioner indexed _new);
3940

4041
IPNFT internal ipnft;
4142

4243
/// @dev a map of all IPTs. We're staying with the the initial term "synthesized" to keep the storage layout intact
43-
mapping(uint256 => IPToken) public synthesized;
44+
mapping(uint256 => IIPToken) public synthesized;
4445

4546
/// @dev not used, needed to ensure that storage slots are still in order after 1.1 -> 1.2, use ipTokenImplementation
4647
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
@@ -105,7 +106,7 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable, IControlIPTs {
105106
ipTokenImplementation = _ipTokenImplementation;
106107
}
107108

108-
/**
109+
/**
109110
* @dev sets legacy IPTs on the tokenized mapping
110111
*/
111112
function reinit(WrappedIPToken _wrappedIpTokenImplementation) public onlyOwner reinitializer(6) {
@@ -158,12 +159,17 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable, IControlIPTs {
158159
token.issue(_msgSender(), tokenAmount);
159160
}
160161

161-
function attachIpt(
162-
uint256 ipnftId,
163-
string memory agreementCid,
164-
bytes calldata signedAgreement,
165-
IERC20Metadata tokenContract
166-
) external {
162+
/**
163+
* @notice since 1.4 allows attaching an existing ERC20 contract as IPT
164+
* @param ipnftId the token id on the underlying nft collection
165+
* @param agreementCid a content hash that contains legal terms for IP token owners
166+
* @param signedAgreement the sender's signature over the signed agreemeent text (must be created on the client)
167+
* @return IPToken a wrapped IPToken that represents the tokenized ipnft for permissioners and carries metadata
168+
*/
169+
function attachIpt(uint256 ipnftId, string memory agreementCid, bytes calldata signedAgreement, IERC20Metadata tokenContract)
170+
external
171+
returns (IIPToken)
172+
{
167173
if (_msgSender() != controllerOf(ipnftId)) {
168174
revert MustControlIpnft();
169175
}
@@ -187,6 +193,7 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable, IControlIPTs {
187193
);
188194
emit TokenWrapped(tokenContract, wrappedIpt);
189195
permissioner.accept(wrappedIpt, _msgSender(), signedAgreement);
196+
return wrappedIpt;
190197
}
191198

192199
/**

0 commit comments

Comments
 (0)