Skip to main content

Security

This page summarizes the security measures built into the Catpound vault.

Built-In Protections

SafeMath

All arithmetic operations in the vault use SafeMath (checked math). Overflow and underflow cause the transaction to revert rather than wrapping silently. This prevents a broad class of bugs where unexpected numeric behavior could lead to loss of funds.

Reentrancy Guard

The vault uses a STANDARD-level reentrancy guard (the strictest level). No external call can re-enter the vault during execution. This prevents attacks where a malicious contract could call back into the vault during a transfer to manipulate state.

Donation-Proof Accounting

The vault tracks totalAssets as a separate storage variable rather than reading its on-chain MOTO balance. This means:

  • Sending MOTO directly to the vault contract does not increase totalAssets
  • The share price is only affected by deposits, withdrawals, and compound operations
  • A "donation attack" (inflating share price by sending tokens directly) is ineffective

Dead Shares

On the first deposit, 1,000 cpMOTO shares are permanently burned. This prevents a share price manipulation attack where an attacker could:

  1. Deposit a small amount to be the sole shareholder
  2. Donate a large amount to inflate the share price
  3. Cause subsequent depositors to receive 0 shares due to rounding

With 1,000 dead shares always in circulation, this attack becomes economically impractical. V4.3 additionally requires the first deposit to be at least 100 MOTO (see above).

Checks-Effects-Interactions (CEI) Pattern

All vault functions follow the CEI pattern:

  1. Checks: Validate inputs and conditions
  2. Effects: Update internal state (balances, counters, flags)
  3. Interactions: Make external calls (token transfers, MotoChef operations)

This ordering prevents state inconsistencies if an external call reverts.

Hard Caps

Critical parameters have hardcoded ceilings in the contract that cannot be changed by the admin:

ParameterHard Cap
Maximum exit fee per tier10% (1,000 BPS)
Maximum protocol fee per tier10% (1,000 BPS)
Maximum staked NFTs per user10
Maximum tier ID7 (tiers 0–7)
MotoChef migration timelock144 blocks (~24 hours)

Anti-Gaming: NFT Staking

The vault tracks a stakeBlock when NFTs are staked. If stakeBlock > lastReinvestBlock, the NFT tier contribution is temporarily suppressed until the next compound cycle completes. This prevents users from staking NFTs right before a compound to reduce fees, then immediately unstaking.

Your NFT tier "activates" at the next compound cycle after staking.

Quantum-Resistant Signatures

The vault contract runs on OPNet, which supports ML-DSA (FIPS 204) digital signatures alongside ECDSA and Schnorr. This provides forward-looking protection against quantum computing threats.

Ownership Model

The vault uses a two-step ownership transfer:

  1. Current owner proposes a new owner (transferOwnership)
  2. New owner must explicitly accept (acceptOwnership)

This prevents accidental or malicious ownership transfers. The pending transfer can be cancelled at any time before acceptance.

Emergency Controls

The vault owner has the following emergency capabilities:

  • Pause deposits: Blocks new deposits while withdrawals continue to work
  • Emergency unstake: Force-unstakes everything from MotoChef, making all MOTO liquid (and clears the stakedInChef flag)
  • MotoChef migration: Propose moving to a new staking contract with a 144-block timelock

These are safety valves for responding to upstream issues with MotoChef or other emergency situations.