lens-modules 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/contracts/LensHub.sol +0 -2
  2. package/contracts/base/LensProfiles.sol +50 -3
  3. package/contracts/base/upgradeability/VersionedInitializable.sol +50 -0
  4. package/contracts/interfaces/IHandleTokenURI.sol +11 -0
  5. package/contracts/interfaces/ILensHandles.sol +106 -0
  6. package/contracts/interfaces/ILensHubInitializable.sol +28 -0
  7. package/contracts/interfaces/ILensProfiles.sol +5 -0
  8. package/contracts/libraries/StorageLib.sol +22 -16
  9. package/contracts/libraries/constants/Errors.sol +2 -0
  10. package/contracts/libraries/svgs/Follow/FollowSVG.sol +16 -0
  11. package/contracts/libraries/svgs/Handle/GintoNordFontSVG.sol +9 -0
  12. package/contracts/libraries/svgs/Handle/HandleSVG.sol +255 -0
  13. package/contracts/libraries/svgs/Profile/Body/BodyHoodie.sol +21 -0
  14. package/contracts/libraries/svgs/Profile/Body/BodyJacket.sol +21 -0
  15. package/contracts/libraries/svgs/Profile/Body/BodyTShirt.sol +21 -0
  16. package/contracts/libraries/svgs/Profile/Body/BodyTanktop.sol +21 -0
  17. package/contracts/libraries/svgs/Profile/Body.sol +119 -0
  18. package/contracts/libraries/svgs/Profile/Face.sol +145 -0
  19. package/contracts/libraries/svgs/Profile/Hands.sol +121 -0
  20. package/contracts/libraries/svgs/Profile/Head.sol +33 -0
  21. package/contracts/libraries/svgs/Profile/Headwear/HeadwearBeanie.sol +71 -0
  22. package/contracts/libraries/svgs/Profile/Headwear/HeadwearCrown.sol +67 -0
  23. package/contracts/libraries/svgs/Profile/Headwear/HeadwearFloral.sol +67 -0
  24. package/contracts/libraries/svgs/Profile/Headwear/HeadwearGlasses.sol +67 -0
  25. package/contracts/libraries/svgs/Profile/Headwear/HeadwearHat.sol +79 -0
  26. package/contracts/libraries/svgs/Profile/Headwear/HeadwearIcecream.sol +55 -0
  27. package/contracts/libraries/svgs/Profile/Headwear/HeadwearLeafs.sol +67 -0
  28. package/contracts/libraries/svgs/Profile/Headwear/HeadwearMushroom.sol +83 -0
  29. package/contracts/libraries/svgs/Profile/Headwear/HeadwearNightcap.sol +67 -0
  30. package/contracts/libraries/svgs/Profile/Headwear/HeadwearPartyhat.sol +69 -0
  31. package/contracts/libraries/svgs/Profile/Headwear/HeadwearPlants.sol +71 -0
  32. package/contracts/libraries/svgs/Profile/Headwear/HeadwearSparkles.sol +55 -0
  33. package/contracts/libraries/svgs/Profile/Headwear.sol +155 -0
  34. package/contracts/libraries/svgs/Profile/Helpers.sol +83 -0
  35. package/contracts/libraries/svgs/Profile/Legs.sol +37 -0
  36. package/contracts/libraries/svgs/Profile/Logo.sol +167 -0
  37. package/contracts/libraries/svgs/Profile/ProfileSVG.sol +384 -0
  38. package/contracts/libraries/svgs/Profile/Shoes.sol +37 -0
  39. package/contracts/libraries/svgs/Profile/SimpleProfileSVG.sol +8 -0
  40. package/contracts/misc/ImmutableOwnable.sol +30 -0
  41. package/contracts/misc/LegacyCollectNFT.sol +126 -0
  42. package/contracts/misc/LensHubInitializable.sol +49 -0
  43. package/contracts/misc/PermissionlessCreator.sol +353 -0
  44. package/contracts/misc/ProfileCreationProxy.sol +66 -0
  45. package/contracts/misc/PublicActProxy.sol +109 -0
  46. package/contracts/misc/token-uris/FollowTokenURI.sol +47 -0
  47. package/contracts/misc/token-uris/HandleTokenURI.sol +42 -0
  48. package/contracts/misc/token-uris/ProfileTokenURI.sol +57 -0
  49. package/contracts/misc/token-uris/SimpleProfileTokenURI.sol +57 -0
  50. package/contracts/modules/act/collect/MultirecipientFeeCollectModule.sol +224 -0
  51. package/contracts/modules/act/collect/SimpleFeeCollectModule.sol +79 -0
  52. package/contracts/modules/follow/FeeFollowModule.sol +131 -0
  53. package/contracts/modules/follow/RevertFollowModule.sol +48 -0
  54. package/contracts/modules/reference/DegreesOfSeparationReferenceModule.sol +314 -0
  55. package/contracts/modules/reference/FollowerOnlyReferenceModule.sol +96 -0
  56. package/contracts/modules/reference/TokenGatedReferenceModule.sol +167 -0
  57. package/contracts/namespaces/LensHandles.sol +326 -0
  58. package/contracts/namespaces/TokenHandleRegistry.sol +320 -0
  59. package/contracts/namespaces/constants/Errors.sol +27 -0
  60. package/contracts/namespaces/constants/Events.sol +63 -0
  61. package/contracts/namespaces/constants/Typehash.sol +12 -0
  62. package/contracts/namespaces/constants/Types.sol +21 -0
  63. package/package.json +1 -1
@@ -16,7 +16,6 @@ import {LensImplGetters} from './base/LensImplGetters.sol';
16
16
  import {LensGovernable} from './base/LensGovernable.sol';
17
17
  import {LensProfiles} from './base/LensProfiles.sol';
18
18
  import {LensHubEventHooks} from './base/LensHubEventHooks.sol';
19
- import {LensVersion} from './base/LensVersion.sol';
20
19
 
21
20
  // Libraries
22
21
  import {ActionLib} from './libraries/ActionLib.sol';
@@ -49,7 +48,6 @@ contract LensHub is
49
48
  LensImplGetters,
50
49
  LensHubEventHooks,
51
50
  LensHubStorage,
52
- LensVersion,
53
51
  ILensProtocol
54
52
  {
55
53
  modifier onlyProfileOwnerOrDelegatedExecutor(address expectedOwnerOrDelegatedExecutor, uint256 profileId) {
@@ -129,11 +129,46 @@ abstract contract LensProfiles is LensBaseERC721, ERC2981CollectionRoyalties, IL
129
129
  LensBaseERC721.supportsInterface(interfaceId) || ERC2981CollectionRoyalties.supportsInterface(interfaceId);
130
130
  }
131
131
 
132
+ function transferFromKeepingDelegates(address from, address to, uint256 tokenId) external {
133
+ //solhint-disable-next-line max-line-length
134
+ if (!_isApprovedOrOwner(msg.sender, tokenId)) {
135
+ revert Errors.NotOwnerOrApproved();
136
+ }
137
+
138
+ if (!StorageLib.profileCreatorWhitelisted()[msg.sender]) {
139
+ // Delegates can be maintained on transfers only when executed by whitelisted profile creators, which are
140
+ // trusted entities, for the sake of a better onboarding UX.
141
+ revert Errors.NotAllowed();
142
+ }
143
+
144
+ if (ownerOf(tokenId) != from) {
145
+ revert Errors.InvalidOwner();
146
+ }
147
+
148
+ if (to == address(0)) {
149
+ revert Errors.InvalidParameter();
150
+ }
151
+
152
+ _beforeTokenTransferWithoutClearingDelegates(from, to, tokenId);
153
+
154
+ // Clear approvals from the previous owner
155
+ _approve(address(0), tokenId);
156
+
157
+ unchecked {
158
+ --StorageLib.balances()[from];
159
+ ++StorageLib.balances()[to];
160
+ }
161
+
162
+ StorageLib.getTokenData(tokenId).owner = to;
163
+
164
+ emit Transfer(from, to, tokenId);
165
+ }
166
+
132
167
  function _hasTokenGuardianEnabled(address wallet) internal view returns (bool) {
133
168
  return
134
169
  !wallet.isContract() &&
135
- (StorageLib.tokenGuardianDisablingTimestamp()[wallet] == 0 ||
136
- block.timestamp < StorageLib.tokenGuardianDisablingTimestamp()[wallet]);
170
+ (StorageLib.tokenGuardianDisablingTimestamp()[wallet] == 0 ||
171
+ block.timestamp < StorageLib.tokenGuardianDisablingTimestamp()[wallet]);
137
172
  }
138
173
 
139
174
  function _getRoyaltiesInBasisPointsSlot() internal pure override returns (uint256) {
@@ -159,4 +194,16 @@ abstract contract LensProfiles is LensBaseERC721, ERC2981CollectionRoyalties, IL
159
194
  }
160
195
  super._beforeTokenTransfer(from, to, tokenId);
161
196
  }
162
- }
197
+
198
+ function _beforeTokenTransferWithoutClearingDelegates(
199
+ address from,
200
+ address to,
201
+ uint256 tokenId
202
+ ) internal whenNotPaused {
203
+ if (from != address(0) && _hasTokenGuardianEnabled(from)) {
204
+ // Cannot transfer profile if the guardian is enabled, except at minting time.
205
+ revert Errors.GuardianEnabled();
206
+ }
207
+ super._beforeTokenTransfer(from, to, tokenId);
208
+ }
209
+ }
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.15;
3
+
4
+ import {Errors} from '../../libraries/constants/Errors.sol';
5
+ import {StorageLib} from '../../libraries/StorageLib.sol';
6
+
7
+ /**
8
+ * @title VersionedInitializable
9
+ *
10
+ * @dev Helper contract to implement initializer functions. To use it, replace
11
+ * the constructor with a function that has the `initializer` modifier.
12
+ * WARNING: Unlike constructors, initializer functions must be manually
13
+ * invoked. This applies both to deploying an Initializable contract, as well
14
+ * as extending an Initializable contract via inheritance.
15
+ * WARNING: When used with inheritance, manual care must be taken to not invoke
16
+ * a parent initializer twice, or ensure that all initializers are idempotent,
17
+ * because this is not dealt with automatically as with constructors.
18
+ *
19
+ * This is slightly modified from [Aave's version.](https://github.com/aave/protocol-v2/blob/6a503eb0a897124d8b9d126c915ffdf3e88343a9/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol)
20
+ *
21
+ * @author Lens Protocol, inspired by Aave's implementation, which is in turn inspired by OpenZeppelin's
22
+ * Initializable contract
23
+ */
24
+ abstract contract VersionedInitializable {
25
+ address private immutable originalImpl;
26
+
27
+ /**
28
+ * @dev Modifier to use in the initializer function of a contract.
29
+ */
30
+ modifier initializer() {
31
+ if (address(this) == originalImpl) {
32
+ revert Errors.CannotInitImplementation();
33
+ }
34
+ if (getRevision() <= StorageLib.getLastInitializedRevision()) {
35
+ revert Errors.Initialized();
36
+ }
37
+ StorageLib.setLastInitializedRevision(getRevision());
38
+ _;
39
+ }
40
+
41
+ constructor() {
42
+ originalImpl = address(this);
43
+ }
44
+
45
+ /**
46
+ * @dev returns the revision number of the contract
47
+ * Needs to be defined in the inherited class as a constant.
48
+ **/
49
+ function getRevision() internal pure virtual returns (uint256);
50
+ }
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity ^0.8.15;
4
+
5
+ interface IHandleTokenURI {
6
+ function getTokenURI(
7
+ uint256 tokenId,
8
+ string memory localName,
9
+ string memory namespace
10
+ ) external view returns (string memory);
11
+ }
@@ -0,0 +1,106 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity >=0.6.0;
4
+
5
+ import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';
6
+
7
+ /**
8
+ * @title ILensHandles
9
+ * @author Lens Protocol
10
+ *
11
+ * @notice This is the interface for the LensHandles contract that is responsible for minting and burning handle NFTs.
12
+ * A handle is composed of a local name and a namespace, separated by a dot.
13
+ * Example: `satoshi.lens` is a handle composed of the local name `satoshi` and the namespace `lens`.
14
+ */
15
+ interface ILensHandles is IERC721 {
16
+ /**
17
+ * @notice Mints a handle NFT in the given namespace.
18
+ * @custom:permissions Only LensHandles contract's owner or LensHub.
19
+ *
20
+ * @param to The address to mint the handle to.
21
+ * @param localName The local name of the handle (the part before ".lens").
22
+ *
23
+ * @return uint256 The ID of the handle NFT minted.
24
+ */
25
+ function mintHandle(address to, string calldata localName) external returns (uint256);
26
+
27
+ /**
28
+ * @notice Burns a handle NFT.
29
+ * @custom:permissions Owner of Handle NFT.
30
+ *
31
+ * @param tokenId The ID of the handle NFT to burn.
32
+ */
33
+ function burn(uint256 tokenId) external;
34
+
35
+ /**
36
+ * @notice Gets the namespace of the contract. It's 'lens' for the LensHandles contract.
37
+ *
38
+ * @return string The namespace of the contract.
39
+ */
40
+ function getNamespace() external pure returns (string memory);
41
+
42
+ /**
43
+ * @notice Gets the hash of the namespace of the contract. It's keccak256('lens') for the LensHandles contract.
44
+ *
45
+ * @return bytes32 The hash of the namespace of the contract.
46
+ */
47
+ function getNamespaceHash() external pure returns (bytes32);
48
+
49
+ /**
50
+ * @notice Returns whether `tokenId` exists.
51
+ *
52
+ * Tokens start existing when they are minted (`_mint`),
53
+ * and stop existing when they are burned (`_burn`).
54
+ *
55
+ * @return bool Whether the token exists.
56
+ */
57
+ function exists(uint256 tokenId) external view returns (bool);
58
+
59
+ /**
60
+ * @notice Returns the amount of tokens in circulation.
61
+ *
62
+ * @return uint256 The current total supply of tokens.
63
+ */
64
+ function totalSupply() external view returns (uint256);
65
+
66
+ /**
67
+ * @notice Returns the HandleTokenURI contract address.
68
+ *
69
+ * @return address The HandleTokenURI contract address.
70
+ */
71
+ function getHandleTokenURIContract() external view returns (address);
72
+
73
+ /**
74
+ * @notice Sets the HandleTokenURI contract address.
75
+ * @custom:permissions Only LensHandles contract's owner
76
+ *
77
+ * @param handleTokenURIContract The HandleTokenURI contract address to set.
78
+ */
79
+ function setHandleTokenURIContract(address handleTokenURIContract) external;
80
+
81
+ /**
82
+ * @notice DANGER: Triggers disabling the profile protection mechanism for the msg.sender, which will allow
83
+ * transfers or approvals over profiles held by it.
84
+ * Disabling the mechanism will have a timelock before it becomes effective, allowing the owner to re-enable
85
+ * the protection back in case of being under attack.
86
+ * The protection layer only applies to EOA wallets.
87
+ */
88
+ function DANGER__disableTokenGuardian() external;
89
+
90
+ /**
91
+ * @notice Enables back the profile protection mechanism for the msg.sender, preventing profile transfers or
92
+ * approvals (except when revoking them).
93
+ * The protection layer only applies to EOA wallets.
94
+ */
95
+ function enableTokenGuardian() external;
96
+
97
+ /**
98
+ * @notice Returns the timestamp at which the Token Guardian will become effectively disabled.
99
+ *
100
+ * @param wallet The address to check the timestamp for.
101
+ *
102
+ * @return uint256 The timestamp at which the Token Guardian will become effectively disabled.
103
+ * Max 256-bit unsigned integer value if enabled.
104
+ */
105
+ function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256);
106
+ }
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity >=0.6.0;
4
+
5
+ /**
6
+ * @title ILensHub
7
+ * @author Lens Protocol
8
+ *
9
+ * @notice This is the interface for the LensHub contract, the main entry point for the Lens Protocol.
10
+ * You'll find all the events and external functions, as well as the reasoning behind them here.
11
+ */
12
+ interface ILensHubInitializable {
13
+ /**
14
+ * @notice Initializes the LensHub, setting the initial governance address, the name and symbol of the profiles
15
+ * in the LensNFTBase contract, and Protocol State (Paused).
16
+ * @dev This is assuming a proxy pattern is implemented.
17
+ * @custom:permissions Callable once.
18
+ *
19
+ * @param name The name of the Profile NFT.
20
+ * @param symbol The symbol of the Profile NFT.
21
+ * @param newGovernance The governance address to set.
22
+ */
23
+ function initialize(
24
+ string calldata name,
25
+ string calldata symbol,
26
+ address newGovernance
27
+ ) external;
28
+ }
@@ -29,4 +29,9 @@ interface ILensProfiles is ILensERC721 {
29
29
  * @return uint256 The timestamp at which the Token Guardian will become effectively disabled. Zero if enabled.
30
30
  */
31
31
  function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256);
32
+
33
+ /**
34
+ * @notice allows transferring of profile but keeping the delegate settings
35
+ */
36
+ function transferFromKeepingDelegates(address from, address to, uint256 tokenId) external;
32
37
  }
@@ -8,7 +8,7 @@ library StorageLib {
8
8
  // uint256 constant NAME_SLOT = 0;
9
9
  // uint256 constant SYMBOL_SLOT = 1;
10
10
  uint256 constant TOKEN_DATA_MAPPING_SLOT = 2;
11
- // uint256 constant BALANCES_SLOT = 3;
11
+ uint256 constant BALANCES_SLOT = 3;
12
12
  // uint256 constant TOKEN_APPROVAL_MAPPING_SLOT = 4;
13
13
  // uint256 constant OPERATOR_APPROVAL_MAPPING_SLOT = 5;
14
14
  // Slot 6 is deprecated in Lens V2. In V1 it was used for ERC-721 Enumerable's `ownedTokens`.
@@ -97,9 +97,9 @@ library StorageLib {
97
97
  }
98
98
 
99
99
  function tokenGuardianDisablingTimestamp()
100
- internal
101
- pure
102
- returns (mapping(address => uint256) storage _tokenGuardianDisablingTimestamp)
100
+ internal
101
+ pure
102
+ returns (mapping(address => uint256) storage _tokenGuardianDisablingTimestamp)
103
103
  {
104
104
  assembly {
105
105
  _tokenGuardianDisablingTimestamp.slot := TOKEN_GUARDIAN_DISABLING_TIMESTAMP_MAPPING_SLOT
@@ -114,6 +114,12 @@ library StorageLib {
114
114
  }
115
115
  }
116
116
 
117
+ function balances() internal pure returns (mapping(address => uint256) storage _balances) {
118
+ assembly {
119
+ _balances.slot := BALANCES_SLOT
120
+ }
121
+ }
122
+
117
123
  function blockedStatus(
118
124
  uint256 blockerProfileId
119
125
  ) internal pure returns (mapping(uint256 => bool) storage _blockedStatus) {
@@ -131,9 +137,9 @@ library StorageLib {
131
137
  }
132
138
 
133
139
  function profileIdByHandleHash()
134
- internal
135
- pure
136
- returns (mapping(bytes32 => uint256) storage _profileIdByHandleHash)
140
+ internal
141
+ pure
142
+ returns (mapping(bytes32 => uint256) storage _profileIdByHandleHash)
137
143
  {
138
144
  assembly {
139
145
  _profileIdByHandleHash.slot := PROFILE_ID_BY_HANDLE_HASH_MAPPING_SLOT
@@ -141,9 +147,9 @@ library StorageLib {
141
147
  }
142
148
 
143
149
  function profileCreatorWhitelisted()
144
- internal
145
- pure
146
- returns (mapping(address => bool) storage _profileCreatorWhitelisted)
150
+ internal
151
+ pure
152
+ returns (mapping(address => bool) storage _profileCreatorWhitelisted)
147
153
  {
148
154
  assembly {
149
155
  _profileCreatorWhitelisted.slot := PROFILE_CREATOR_WHITELIST_MAPPING_SLOT
@@ -151,9 +157,9 @@ library StorageLib {
151
157
  }
152
158
 
153
159
  function migrationAdminWhitelisted()
154
- internal
155
- pure
156
- returns (mapping(address => bool) storage _migrationAdminWhitelisted)
160
+ internal
161
+ pure
162
+ returns (mapping(address => bool) storage _migrationAdminWhitelisted)
157
163
  {
158
164
  assembly {
159
165
  _migrationAdminWhitelisted.slot := MIGRATION_ADMINS_WHITELISTED_MAPPING_SLOT
@@ -161,9 +167,9 @@ library StorageLib {
161
167
  }
162
168
 
163
169
  function legacyCollectFollowValidationHelper()
164
- internal
165
- pure
166
- returns (mapping(address => uint256) storage _legacyCollectFollowValidationHelper)
170
+ internal
171
+ pure
172
+ returns (mapping(address => uint256) storage _legacyCollectFollowValidationHelper)
167
173
  {
168
174
  assembly {
169
175
  _legacyCollectFollowValidationHelper.slot := LEGACY_COLLECT_FOLLOW_VALIDATION_HELPER_MAPPING_SLOT
@@ -49,4 +49,6 @@ library Errors {
49
49
 
50
50
  // Migration Errors
51
51
  error NotMigrationAdmin();
52
+
53
+ error NotAllowed();
52
54
  }
@@ -0,0 +1,16 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ library FollowSVG {
5
+ uint8 private constant MAX_GOLD_TOKEN_ID = 10;
6
+
7
+ function getFollowSVG(uint256 followTokenId) public pure returns (string memory) {
8
+ if (followTokenId <= MAX_GOLD_TOKEN_ID) {
9
+ return
10
+ '<svg xmlns="http://www.w3.org/2000/svg" width="275" height="275" fill="none"><g><path fill="url(#b)" d="M0 0h275v275H0z"/><path fill="url(#c)" stroke="#B96326" stroke-linecap="square" stroke-linejoin="round" stroke-width="4" d="M168.9 116.8v0a1 1 0 0 1-1.8-.8v0-2.7c-1.1-37.7-58.1-37.7-59.1 0v2.7a1 1 0 0 1-1.9.8v0l-2-2C76.8 89 36.5 129.3 62.5 156.6l2 2a113.3 113.3 0 0 0 73.1 31.3s0 0 0 0 41.8 0 73.2-31.3a81 81 0 0 0 2-2c26-27.4-14.4-67.6-41.9-41.6l-2 1.9Z"/><g><path fill="#B96326" d="M127.3 152.2a1 1 0 0 0-1-1.3H125a1 1 0 0 1-1-1v-1.8c0-.6.4-1 1-1h2.8a1 1 0 0 0 1-.8l.7-3.1a1 1 0 0 0-1-1.2h-1.7a1 1 0 0 1-1-1v-2c0-.5.4-1 1-1h3.2a1 1 0 0 0 1-.7l1-4.6a1 1 0 0 1 1-.8h3a1 1 0 0 1 1 1.2l-.9 3.7a1 1 0 0 0 1 1.2h3a1 1 0 0 0 1-.7l1.2-4.6a1 1 0 0 1 1-.8h3a1 1 0 0 1 1 1.2l-1 3.7a1 1 0 0 0 1 1.2h1.8a1 1 0 0 1 1 1.3l-.5 1.8a1 1 0 0 1-1 .8H146a1 1 0 0 0-1 .7l-.7 3.1a1 1 0 0 0 1 1.3h1.8a1 1 0 0 1 1 1.2l-.5 1.9a1 1 0 0 1-1 .7h-2.8a1 1 0 0 0-1 .8l-1.3 5.5a1 1 0 0 1-1 .8h-3a1 1 0 0 1-1-1.3l1.2-4.5a1 1 0 0 0-1-1.3h-3.1a1 1 0 0 0-1 .8l-1.3 5.5a1 1 0 0 1-1 .8h-3a1 1 0 0 1-1-1.3l1.1-4.5Zm10.8-5a1 1 0 0 0 1-.8l.7-3.3a1 1 0 0 0-1-1.2h-3.2a1 1 0 0 0-1 .7l-.8 3.3a1 1 0 0 0 1 1.3h3.3Z"/></g></g><defs><radialGradient id="b" cx="0" cy="0" r="1" gradientTransform="matrix(275 -275 362 362 0 275)" gradientUnits="userSpaceOnUse"><stop stop-color="#FFE7A5"/><stop offset="1" stop-color="#FFF2CE"/></radialGradient><radialGradient id="c" cx="0" cy="0" r="1" gradientTransform="matrix(0 83 -132 0 137.5 107.1)" gradientUnits="userSpaceOnUse"><stop stop-color="#FFDF85"/><stop offset=".9" stop-color="#F8C944"/></radialGradient></defs></svg>';
11
+ } else {
12
+ return
13
+ '<svg xmlns="http://www.w3.org/2000/svg" width="275" height="275" fill="none"><g><path fill="url(#green)" d="M0 0h275v275H0z"/><path fill="#A0D170" stroke="#000" stroke-linecap="square" stroke-linejoin="round" stroke-width="4" d="M168.9 116.8v0a1 1 0 0 1-1.8-.8v0-2.7c-1.1-37.7-58.1-37.7-59.1 0v2.7a1 1 0 0 1-1.9.8v0l-2-2C76.8 89 36.5 129.3 62.5 156.6l2 2a113.3 113.3 0 0 0 73.1 31.3s41.8 0 73.2-31.3a81 81 0 0 0 2-2c26-27.4-14.4-67.6-41.9-41.6l-2 1.9Z"/><g><path fill="#000" d="M127.3 152.2a1 1 0 0 0-1-1.3H125a1 1 0 0 1-1-1v-1.8c0-.6.4-1 1-1h2.8a1 1 0 0 0 1-.8l.7-3.1a1 1 0 0 0-1-1.2h-1.7a1 1 0 0 1-1-1v-2c0-.5.4-1 1-1h3.2a1 1 0 0 0 1-.7l1-4.6a1 1 0 0 1 1-.8h3a1 1 0 0 1 1 1.2l-.9 3.7a1 1 0 0 0 1 1.2h3a1 1 0 0 0 1-.7l1.2-4.6a1 1 0 0 1 1-.8h3a1 1 0 0 1 1 1.2l-1 3.7a1 1 0 0 0 1 1.2h1.8a1 1 0 0 1 1 1.3l-.5 1.8a1 1 0 0 1-1 .8H146a1 1 0 0 0-1 .7l-.7 3.1a1 1 0 0 0 1 1.3h1.8a1 1 0 0 1 1 1.2l-.5 1.9a1 1 0 0 1-1 .7h-2.8a1 1 0 0 0-1 .8l-1.3 5.5a1 1 0 0 1-1 .8h-3a1 1 0 0 1-1-1.3l1.2-4.5a1 1 0 0 0-1-1.3h-3.1a1 1 0 0 0-1 .8l-1.3 5.5a1 1 0 0 1-1 .8h-3a1 1 0 0 1-1-1.3l1.1-4.5Zm10.8-5a1 1 0 0 0 1-.8l.7-3.3a1 1 0 0 0-1-1.2h-3.2a1 1 0 0 0-1 .7l-.8 3.3a1 1 0 0 0 1 1.3h3.3Z"/></g></g><defs><radialGradient id="green" cx="0" cy="0" r="1" gradientTransform="matrix(275 -275 362 362 0 275)" gradientUnits="userSpaceOnUse"><stop stop-color="#DFFFBF"/><stop offset="1" stop-color="#EFD"/></radialGradient></defs></svg>';
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,9 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ library GintoNordFontSVG {
5
+ function getFontStyle() external pure returns (string memory) {
6
+ return
7
+ '<style>@font-face{font-family:"Ginto Nord Medium";src:url(data:application/font-woff;charset=utf-8;base64,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) format("woff"); font-weight:normal;font-style:normal;}</style>';
8
+ }
9
+ }