@@ -3,20 +3,9 @@ pragma solidity ^0.8.24;
33
44import "@openzeppelin/contracts/access/Ownable.sol " ;
55import "@openzeppelin/contracts/utils/ReentrancyGuard.sol " ;
6- import "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
7-
8- // Interface for the vault contract to get staked amounts
9- interface IVault {
10- function balanceOf (address account ) external view returns (uint256 );
11- }
126
137contract TalentPlusSubscription is Ownable , ReentrancyGuard {
148
15- // TALENT token address for balance checking
16- IERC20 public immutable TALENT_TOKEN;
17- // Array of vault addresses to check staked amounts
18- address [] public vaultAddresses;
19-
209 // Mapping to store trusted signers
2110 mapping (address => bool ) public trustedSigners;
2211
@@ -57,18 +46,9 @@ contract TalentPlusSubscription is Ownable, ReentrancyGuard {
5746 event UserSubscriptionExtended (address indexed wallet , string subscriptionSlug , uint256 expirationTime , uint256 startTime , address payer , uint256 pricePaid );
5847 event TrustedSignerAdded (address indexed signer );
5948 event TrustedSignerRemoved (address indexed signer );
60- event VaultAddressAdded (address indexed vaultAddress );
61- event VaultAddressRemoved (address indexed vaultAddress );
6249
63- constructor (address initialOwner , address talentTokenAddress , address [] memory initialVaultAddresses ) Ownable (initialOwner) {
50+ constructor (address initialOwner ) Ownable (initialOwner) {
6451 trustedSigners[initialOwner] = true ;
65- TALENT_TOKEN = IERC20 (talentTokenAddress);
66-
67- // Add initial vault addresses
68- for (uint256 i = 0 ; i < initialVaultAddresses.length ; i++ ) {
69- require (initialVaultAddresses[i] != address (0 ), "Invalid vault address " );
70- vaultAddresses.push (initialVaultAddresses[i]);
71- }
7252 }
7353
7454 /**
@@ -105,77 +85,6 @@ contract TalentPlusSubscription is Ownable, ReentrancyGuard {
10585 return trustedSigners[signer];
10686 }
10787
108- /**
109- * @notice Adds a vault address to the list of vaults to check for staked amounts
110- * @param vaultAddress The vault address to add
111- * @dev Can only be called by the owner or trusted signers
112- */
113- function addVaultAddress (address vaultAddress ) external {
114- require (owner () == msg .sender || trustedSigners[msg .sender ], "Only owner or trusted signers can add vault addresses " );
115- require (vaultAddress != address (0 ), "Invalid vault address " );
116-
117- // Check if vault address already exists
118- for (uint256 i = 0 ; i < vaultAddresses.length ; i++ ) {
119- require (vaultAddresses[i] != vaultAddress, "Vault address already exists " );
120- }
121-
122- vaultAddresses.push (vaultAddress);
123- emit VaultAddressAdded (vaultAddress);
124- }
125-
126- /**
127- * @notice Removes a vault address from the list of vaults
128- * @param vaultAddress The vault address to remove
129- * @dev Can only be called by the owner or trusted signers
130- */
131- function removeVaultAddress (address vaultAddress ) external {
132- require (owner () == msg .sender || trustedSigners[msg .sender ], "Only owner or trusted signers can remove vault addresses " );
133-
134- bool found = false ;
135- for (uint256 i = 0 ; i < vaultAddresses.length ; i++ ) {
136- if (vaultAddresses[i] == vaultAddress) {
137- // Move the last element to the position of the element to delete
138- vaultAddresses[i] = vaultAddresses[vaultAddresses.length - 1 ];
139- // Remove the last element
140- vaultAddresses.pop ();
141- found = true ;
142- break ;
143- }
144- }
145-
146- require (found, "Vault address not found " );
147- emit VaultAddressRemoved (vaultAddress);
148- }
149-
150- /**
151- * @notice Gets all vault addresses
152- * @return An array of all vault addresses
153- */
154- function getVaultAddresses () external view returns (address [] memory ) {
155- return vaultAddresses;
156- }
157-
158- /**
159- * @notice Gets the total number of vault addresses
160- * @return The number of vault addresses
161- */
162- function getVaultAddressCount () external view returns (uint256 ) {
163- return vaultAddresses.length ;
164- }
165-
166- /**
167- * @notice Helper function to calculate total staked amount across all vaults
168- * @param wallet The wallet address to check
169- * @return totalStaked The total amount staked across all vaults
170- */
171- function _getTotalVaultStaked (address wallet ) internal view returns (uint256 totalStaked ) {
172- totalStaked = 0 ;
173- for (uint256 i = 0 ; i < vaultAddresses.length ; i++ ) {
174- totalStaked += IVault (vaultAddresses[i]).balanceOf (wallet);
175- }
176- return totalStaked;
177- }
178-
17988 /**
18089 * @notice Adds a new subscription model
18190 * @param subscriptionSlug The subscription slug string for the subscription model
@@ -195,7 +104,7 @@ contract TalentPlusSubscription is Ownable, ReentrancyGuard {
195104 require (owner () == msg .sender || trustedSigners[msg .sender ], "Only owner or trusted signers can add subscription models " );
196105 require (bytes (subscriptionSlug).length > 0 , "Subscription slug cannot be empty " );
197106 require (durationInSeconds > 0 , "Duration must be greater than 0 " );
198- require (price > 0 , "Price must be greater than 0 " );
107+ require (price > 0 || discountPercentage == 100 , "Price must be greater than 0 unless discount is 100% " );
199108 require (discountPercentage <= 100 , "Discount percentage cannot exceed 100% " );
200109 require (! subscriptionModels[subscriptionSlug].active, "Subscription model already exists " );
201110
@@ -234,7 +143,7 @@ contract TalentPlusSubscription is Ownable, ReentrancyGuard {
234143 require (bytes (subscriptionSlug).length > 0 , "Subscription slug cannot be empty " );
235144 require (subscriptionModels[subscriptionSlug].active, "Subscription model does not exist " );
236145 require (durationInSeconds > 0 , "Duration must be greater than 0 " );
237- require (price > 0 , "Price must be greater than 0 " );
146+ require (price > 0 || discountPercentage == 100 , "Price must be greater than 0 unless discount is 100% " );
238147 require (discountPercentage <= 100 , "Discount percentage cannot exceed 100% " );
239148
240149 subscriptionModels[subscriptionSlug].durationInSeconds = durationInSeconds;
@@ -439,60 +348,6 @@ contract TalentPlusSubscription is Ownable, ReentrancyGuard {
439348 return (model.durationInSeconds, model.price, model.discountPercentage, model.talentRequiredForDiscount, model.active);
440349 }
441350
442- /**
443- * @notice Calculates the discounted price for a subscription based on TALENT holdings (balance + vault staking across all vaults)
444- * @param subscriptionSlug The subscription slug
445- * @param wallet The wallet address to check TALENT balance and vault staking for
446- * @return finalPrice The final price after applying discount (if applicable)
447- * @return discountApplied Whether a discount was applied
448- * @return discountAmount The amount of discount applied (0 if no discount)
449- */
450- function calculateDiscountedPrice (string memory subscriptionSlug , address wallet ) external view returns (uint256 finalPrice , bool discountApplied , uint256 discountAmount ) {
451- require (bytes (subscriptionSlug).length > 0 , "Subscription slug cannot be empty " );
452- require (wallet != address (0 ), "Invalid wallet address " );
453-
454- SubscriptionModel memory model = subscriptionModels[subscriptionSlug];
455- require (model.active, "Subscription model is not active " );
456-
457- uint256 talentBalance = TALENT_TOKEN.balanceOf (wallet);
458- uint256 vaultStaked = _getTotalVaultStaked (wallet);
459- uint256 totalTalentHoldings = talentBalance + vaultStaked;
460-
461- // Check if wallet qualifies for discount (TALENT balance + vault staking)
462- if (totalTalentHoldings >= model.talentRequiredForDiscount && model.discountPercentage > 0 ) {
463- discountAmount = (model.price * model.discountPercentage) / 100 ;
464- finalPrice = model.price - discountAmount;
465- discountApplied = true ;
466- } else {
467- finalPrice = model.price;
468- discountApplied = false ;
469- discountAmount = 0 ;
470- }
471-
472- return (finalPrice, discountApplied, discountAmount);
473- }
474-
475- /**
476- * @notice Gets the total TALENT holdings for a user (balance + vault staking across all vaults)
477- * @param wallet The wallet address to check TALENT holdings for
478- * @return totalTalentHoldings The total TALENT holdings (balance + vault staked across all vaults)
479- * @return talentBalance The TALENT token balance in the wallet
480- * @return vaultStaked The TALENT tokens staked across all vaults
481- */
482- function getUserTalentHoldings (address wallet ) external view returns (
483- uint256 totalTalentHoldings ,
484- uint256 talentBalance ,
485- uint256 vaultStaked
486- ) {
487- require (wallet != address (0 ), "Invalid wallet address " );
488-
489- talentBalance = TALENT_TOKEN.balanceOf (wallet);
490- vaultStaked = _getTotalVaultStaked (wallet);
491- totalTalentHoldings = talentBalance + vaultStaked;
492-
493- return (totalTalentHoldings, talentBalance, vaultStaked);
494- }
495-
496351 /**
497352 * @notice Gets the total number of subscription models
498353 * @return The number of subscription models
0 commit comments