Zero Staking

QuantstampRepository at commit 5f93318

Quantstamp reviewed Zero Staking on 19 Jun 2024: 10 findings, 0 critical; 6 marked fixed, 4 acknowledged.

No open critical findings
Open the reportOpen Zero Staking’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings10

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

SeverityOpenAcknowledgedFixed
Critical000
High002
Medium002
Low042
LowCompromised Owner or Operators Can Steal All Users' Escrowed FundsAcknowledged

Suppose `A` is an address controlled by an owner (or operator). An owner (or operator) can create a match with high match fees and have one of the players being `A` and other players as victims. The owner (or operator) can then call `endMatch()` where the payout to `A` is the total of all the match fees from each player and every other player gets zero payouts, effectively stealing funds from all the other players. Per communication with the team, the operators are addresses owned by the team, not some third parties, so the risk here is considered acceptable.

LowPrivileged Roles and OwnershipAcknowledged

In `StakingBase.sol`: `Owner`: - The owner can steal all the rewards (not just the leftovers) by using `withdrawLeftoverRewards()`. In `Escrow.sol`: `Owner and Operators`: - Can force sending funds back to users by calling `releaseFunds()`. In `Match.sol`: `Owner and Operators`: - Can start and end a match by calling `startMatch()` and `endMatch()`. Note that ZS-5 allows an owner or operator to steal all users' funds in the Escrow contract. In `OwnableOperable.sol`: `Owner`: - Can add and remove operators by calling `addOperator()`, `addOperators()`, and `removeOperator()`. - Can change and revoke ownership through `Ownable`. In `StakingERC721.sol`: `Owner`: - Can set the tokenURI and base tokenURI by calling `setTokenURI` and `setBaseURI` respectively.

LowThere May Not Be Sufficient Funds in the Contract to Cover the Reward ClaimsAcknowledged

A user can only claim rewards from the contract if there are sufficient reward tokens in the staking contract. However, this heavily relies on the owner to provide funds to the contract to cover any user's claims. There may be times when there won't be sufficient funds in the contract to cover all user's claims.

LowUser Can Stake a Small Amount Initially to Get an Early Unlock TimestampAcknowledged

Since the unlock timestamp is never updated after the initial staking (see below in `_checkRewards()`), a user can game the system by staking an initial small amount (e.g. 1 token) to get an early `unlockTimestamp` and stake more as needed in the future. ``` function _checkRewards(Staker storage staker) internal { if (staker.amountStaked > 0) { // It isn't their first stake, snapshot pending rewards staker.owedRewards = _getPendingRewards(staker); } else { // Log the time at which this stake becomes claimable or unstakable // This is only done once per user staker.unlockTimestamp = block.timestamp + timeLockPeriod; } } ``` Along the same line of reasoning, users could unstake all but 1 `wei` to bypass any unlock period in their next staking operation since the corresponding entry in the `stakers` mapping is not deleted.

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 (12)

  • https://github.com/zer0-os/zModules/contracts/access/IOwnableOperable.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/access/OwnableOperable.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/staking/ERC20/StakingERC20.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/escrow/Escrow.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/staking/IStakingBase.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/staking/StakingBase.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/staking/ERC721/IStakingERC721.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/match/Match.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/escrow/IEscrow.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/match/IMatch.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/staking/ERC721/StakingERC721.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87
  • https://github.com/zer0-os/zModules/contracts/staking/ERC20/IStakingERC20.sol at commit 5f93318541de502e40d80354f1af21e6e8791f87

Part of Zero Staking’s security record

Zero Staking
Audits1 audit by 1 firmLast audit Jun 2024, by Quantstamp.
Critical findingsNo open critical findingsIn 1 report.
Open Zero Staking’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