Subscription Token Protocol V2

QuantstampRepository at commit 2b993d1

Quantstamp reviewed Subscription Token Protocol V2 on 30 May 2024: 16 findings, 0 critical; 12 marked fixed, 4 acknowledged.

No open critical findings
Open the reportOpen Subscription Token Protocol V2’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings16

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High001
Medium001
Low0410
LowA `SPTV2` Instance Cannot Have More than `256` Different Reward CurvesAcknowledged

The identifier of a reward curve is stored in an `uint8`. As a result, the function `RewardPoolLib.createCurve()` will revert if there are already `256` created reward curves. This limitation should be documented to creators.

LowImportant Addresses Are Not Updated in Two StepsAcknowledged

The addresses receiving the fees for the client and the protocol can be updated with the functions `updateClientFeeRecipient()` and `updateProtocolFeeRecipient()`. However, only the current recipient can execute this function. As a result, if an incorrect address owned by no one or unable to receive fees is set, the amount transferred to this address can be considered lost. The likelihood is assessed as Low.

LowPrivileged RolesAcknowledged

We include the observed privileged roles and their capabilities below: `STPV2Factory` - `owner` as in the owner of the Subscription Factory contract; the Subscription Token Protocol team. - `setProtocolFeeRecipient()` - `setDeployFee()` - Client fee recipient - `updateClientFeeRecipient()` - Protocol fee recipient - `updateProtocolFeeRecipient()` `STPV2` - `owner`, as in, the deployer of the Subscription Token contract; the entity to which people are subscribing - `refund()` an account and clear their subscription - `grantTime()` or `revokeTime()` to an address subscribing - `issueRewardShares()` to grant rewards to a user, independent of any reward curves defined - `transferFunds()` to an address different from the `_transferRecipient` stored in the contracts; although, anyone can invoke this function to transfer to the defined `_transferRecipient` address - `updateMetadata()` to redefine the URI used for the NFTs - `setTransferRecipient()` defining a new address to receive the owner's portion of the subscription revenue - `setGlobalSupplyCap()` defining the amount of subscriptions that can exist for this given Subscription - `createTier()` defining a new subscription tier available for subscribers, or `updateTier()` redefining the parameters for an existing tier - `setReferralCode()` assigning a basis points reward for a specified referrer address - `issueRewardShares()` to give reward shares to a specified account - `createRewardCurve()` for a subscription - `recoverCurrency()` to withdraw any funds that are not the currency defined for the subscription to any specified address - `ROLE_MANAGER` - `grantTime()` or `revokeTime()`to an address subscribing - `updateMetadata()` to redefine the URI used for the NFTs - `createTier()` defining a new subscription tier available for subscribers, or `updateTier()` redefining the parameters for an existing tier - `createRewardCurve()` for a subscription - `ROLE_AGENT` - `grantTime()` or `revokeTime()` to an address subscribing

LowRisks that the Subscription Owner Can Steal Funds From the ContractAcknowledged

While there are some mitigation strategies to prevent users from withdrawing the contract-denominated currency in the contract, as shown in `recoverCurrency()`, it does not actually prevent the owner from stealing all the funds in the contract. Note that users deposit currency into the contract through `purchase()`, which allocates the deposited amount as a reward. So, to drain the contract's currency, it suffices to claim all the rewards available allocated in the contract. To this end, the owner can call `issueRewardShares()` to issue a large number of shares to an account he controls, diluting the shares of other users and effectively stealing the rewards from other users.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (52)

  • https://github.com/withfabricxyz/stp-v2/test/Initialization.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/interfaces/IERC5192.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/SubscriberLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/abstracts/ERC721.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/types/Views.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/ReferralLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Funds.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/SubscriptionLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/abstracts/AccessControlled.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Roles.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/TestImports.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/GateLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/README.md at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Factory.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/script/setup at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/libraries/RewardPoolLib.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Grants.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/foundry.toml at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/SubscriptionTokenV2.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/abstracts/AccessControlled.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Minting.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/libraries/RewardCurveLib.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/TierManagement.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/CurrencyLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Referrals.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/remappings.txt at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/.gitmodules at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/RewardPoolLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/TierSwitching.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/RewardCurveLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Rewards.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/types/Rewards.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/slither.config.json at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/libraries/TierLib.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/types/Constants.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/STPV2Factory.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/libraries/CurrencyLib.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/interfaces/IERC4906.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/libraries/GateLib.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/.gitignore at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/.vscode/settings.json at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/.github/workflows/test.yml at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Refunds.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/script/slither at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/libraries/TierLib.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/types/Factory.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Fees.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/abstracts/ERC721.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/types/Index.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/.solhint.json at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/test/Recovery.t.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074
  • https://github.com/withfabricxyz/stp-v2/src/STPV2.sol at commit 2b993d16f76c2a0ee93175bf6992696d50dfc074

Part of Subscription Token Protocol V2’s security record

Subscription Token Protocol V2
Audits2 audits by 1 firmLast audit May 2024, by Quantstamp.
Critical findingsNo open critical findingsAcross 2 reports.
Open Subscription Token Protocol V2’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us