-
Notifications
You must be signed in to change notification settings - Fork 0
/
UniqueRoyaltyHelper.sol
107 lines (81 loc) · 3.87 KB
/
UniqueRoyaltyHelper.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.19;
import "./UniqueRoyalty.sol";
import "./LibPart.sol";
string constant ROYALTIES_PROPERTY = "royalties";
interface ICollection {
function collectionProperty(string memory key) external view returns (bytes memory);
function property(uint256 tokenId, string memory key) external view returns (bytes memory);
}
struct RoyaltyAmount {
CrossAddress crossAddress;
uint amount;
}
contract UniqueRoyaltyHelper {
function encodePart(UniqueRoyaltyPart memory part) public pure returns (bytes memory) {
(uint256 encodedMeta, uint256 encodedAddress) = UniqueRoyalty.encodePart(part);
return abi.encodePacked(encodedMeta, encodedAddress);
}
function decodePart(bytes memory data) public pure returns (UniqueRoyaltyPart memory) {
return UniqueRoyalty.decodePart(data);
}
// todo - implement smth better - check royalties sum is lte 100%
function validatePart(bytes memory b) public pure returns (bool isValid) {
isValid = b.length == 64;
}
function encode(UniqueRoyaltyPart[] memory royalties) public pure returns (bytes memory) {
return UniqueRoyalty.encode(royalties);
}
function decode(bytes memory data) public pure returns (UniqueRoyaltyPart[] memory) {
return UniqueRoyalty.decode(data);
}
// todo - implement smth better - check royalties sum is lte 100%
function validate(bytes memory b) public pure returns (bool) {
return b.length % 64 == 0;
}
function getTokenRoyalty(address collection, uint tokenId) public view returns (UniqueRoyaltyPart[] memory) {
try ICollection(collection).property(tokenId, ROYALTIES_PROPERTY) returns (bytes memory encoded) {
return UniqueRoyalty.decode(encoded);
} catch {
return new UniqueRoyaltyPart[](0);
}
}
function getCollectionRoyalty(address collection) public view returns (UniqueRoyaltyPart[] memory) {
try ICollection(collection).collectionProperty(ROYALTIES_PROPERTY) returns (bytes memory encoded) {
return UniqueRoyalty.decode(encoded);
} catch {
return new UniqueRoyaltyPart[](0);
}
}
function getRoyalty(address collection, uint tokenId) public view returns (UniqueRoyaltyPart[] memory royalty) {
royalty = getTokenRoyalty(collection, tokenId);
if (royalty.length == 0) {
royalty = getCollectionRoyalty(collection);
}
}
function calculateRoyalties(UniqueRoyaltyPart[] memory royalties, bool isPrimarySale, uint sellPrice) public pure returns (RoyaltyAmount[] memory) {
RoyaltyAmount[] memory royaltyAmounts = new RoyaltyAmount[](royalties.length);
uint amountsCount = 0;
for (uint i = 0; i < royalties.length; i++) {
if (isPrimarySale == royalties[i].isPrimarySaleOnly) {
uint amount = (sellPrice * royalties[i].value) / (10 ** (royalties[i].decimals));
royaltyAmounts[amountsCount] = RoyaltyAmount({
crossAddress: royalties[i].crossAddress,
amount: amount
});
amountsCount += 1;
}
}
// shrink royaltyAmounts to amountsCount length
assembly { mstore(royaltyAmounts, amountsCount) }
return royaltyAmounts;
}
function calculateForPrimarySale(address collection, uint tokenId, uint sellPrice) public view returns (RoyaltyAmount[] memory) {
UniqueRoyaltyPart[] memory royalties = getRoyalty(collection, tokenId);
return calculateRoyalties(royalties, true, sellPrice);
}
function calculate(address collection, uint tokenId, uint sellPrice) public view returns (RoyaltyAmount[] memory) {
UniqueRoyaltyPart[] memory royalties = getRoyalty(collection, tokenId);
return calculateRoyalties(royalties, false, sellPrice);
}
}