Security Features
Comprehensive overview of security mechanisms in DogWithCap smart contracts.
Security Architecture
DogWithCap implements multiple layers of security to protect user funds and ensure platform integrity.
Defense in Depth
Layer 1: OpenZeppelin Battle-Tested Contracts
Layer 2: Access Control & Ownership
Layer 3: Reentrancy Protection
Layer 4: Rate Limiting
Layer 5: Emergency Controls
Layer 6: Input ValidationCore Security Features
1. Reentrancy Protection
All state-changing functions use OpenZeppelin's ReentrancyGuard.
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract DogWithCapStaking is ReentrancyGuard {
function stake(uint256 amount, address referrer)
external
nonReentrant // β
Protected
{
// State changes before external calls
// ...
}
}Protection Against:
- Recursive calls
- Cross-function reentrancy
- Cross-contract reentrancy
Pattern Used:
- State changes BEFORE external calls
nonReentrantmodifier on all critical functions- Checks-Effects-Interactions pattern
2. Access Control
import "@openzeppelin/contracts/access/Ownable.sol";
contract DogWithCapStaking is Ownable {
// Admin-only functions
function setDailyInterestRate(uint256 newRate)
external
onlyOwner // β
Owner only
{
// ...
}
}Owner Capabilities:
- β Adjust interest rates (within bounds)
- β Pause/unpause contract
- β Deposit rewards
- β Update milestone requirements
- β Process cash out requests
Owner CANNOT:
- β Withdraw user funds
- β Modify user positions
- β Change rate beyond constraints
- β Access user private keys
3. Rate Limiting
uint256 public constant CLAIM_COOLDOWN = 60; // 60 seconds
mapping(address => uint256) public lastActionTime;
modifier rateLimited() {
require(
block.timestamp >= lastActionTime[msg.sender] + CLAIM_COOLDOWN,
"Cooldown active"
);
_;
lastActionTime[msg.sender] = block.timestamp;
}Prevents:
- Spam attacks
- Gas price manipulation
- Flash loan attacks
- Front-running exploits
Applied To:
- Staking
- Claiming interest
- Claiming referrals
- Claiming vesting
- Cash out requests
4. Emergency Pause
import "@openzeppelin/contracts/security/Pausable.sol";
contract DogWithCapStaking is Pausable {
function stake(uint256 amount, address referrer)
external
whenNotPaused // β
Can be paused
{
// ...
}
}When to Pause:
- Critical vulnerability discovered
- Suspicious activity detected
- Maintenance required
- External dependency issues
What Gets Paused:
- All user-facing functions
- Staking
- Claiming
- Cash out requests
What Still Works:
- View functions
- Admin functions
- Emergency withdrawals (if enabled)
5. Input Validation
// Custom errors for gas efficiency
error AmountZero();
error AmountTooLow();
error SelfReferral();
error InvalidPosition();
function stake(uint256 amount, address referrer) external {
if (amount == 0) revert AmountZero();
if (amount < MIN_STAKE_AMOUNT) revert AmountTooLow();
if (msg.sender == referrer) revert SelfReferral();
// Additional validations...
}Validations:
- β Non-zero amounts
- β Minimum thresholds
- β Maximum limits
- β Valid addresses
- β Position ownership
- β Sufficient balances
6. SafeERC20
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
using SafeERC20 for IERC20;
function stake(uint256 amount, address referrer) external {
// β
Safe transfer with return value check
stakingToken.safeTransferFrom(msg.sender, address(this), amount);
}Protects Against:
- Non-standard ERC20 implementations
- Silent failures
- Return value issues
- Token approval edge cases
Economic Security
Interest Rate Constraints
uint256 public constant MIN_DAILY_INTEREST_RATE = 50; // 0.05%
uint256 public constant MAX_DAILY_INTEREST_RATE = 1000; // 1%
function setDailyInterestRate(uint256 newRate, string calldata reason)
external
onlyOwner
{
if (newRate < MIN_DAILY_INTEREST_RATE || newRate > MAX_DAILY_INTEREST_RATE) {
revert InvalidInterestRate();
}
// ...
}Prevents:
- Unrealistic APR promises
- Platform insolvency
- User exploitation
Reward Pool Management
function _processRewardPayout(uint256 requestedAmount)
private
returns (uint256)
{
uint256 contractBalance = stakingToken.balanceOf(address(this));
uint256 reservedForStakes = stats.totalStaked;
uint256 reservedForCashOut = totalCashOutTokensInContract;
uint256 availableForRewards = contractBalance > (reservedForStakes + reservedForCashOut)
? contractBalance - reservedForStakes - reservedForCashOut
: 0;
uint256 maxPayout = availableForRewards < stats.rewardPool
? availableForRewards
: stats.rewardPool;
uint256 payout = requestedAmount > maxPayout ? maxPayout : requestedAmount;
if (payout > 0) {
stats.rewardPool -= payout;
}
return payout;
}Ensures:
- User stakes always protected
- Cash out funds reserved
- Rewards paid from pool only
- Platform solvency maintained
Minimum Stakes
uint256 public constant MIN_STAKE_AMOUNT = 100 * 10**18;Prevents:
- Dust attacks
- Contract spam
- Economic exploits
- Position bloat
Audit Trail
Event Emission
Every significant action emits events:
emit PositionCreated(user, positionId, amount, referrer, timestamp);
emit PositionClaimed(user, positionId, interest, total, days, timestamp);
emit MilestoneAchieved(user, level, bonus, vesting, timestamp);
emit AdminAction(action, target, value, timestamp);Benefits:
- Complete transaction history
- Off-chain monitoring
- Forensic analysis
- User transparency
Interest Rate History
struct InterestRateChange {
uint256 oldRate;
uint256 newRate;
uint256 timestamp;
string reason;
}
InterestRateChange[] public interestRateHistory;Provides:
- Full rate change log
- Justification records
- Historical transparency
- Audit capability
Known Limitations
Understanding limitations is part of security.
1. Permanent Staking
Design: Users cannot withdraw principal.
Mitigation:
- Clearly communicated
- Warning in UI
- Documentation emphasis
- Emergency withdrawal option (admin-enabled)
2. Centralized Rate Control
Design: Owner can adjust interest rates.
Mitigation:
- Rate change constraints (0.05% - 1%)
- Change history on-chain
- Reason required
- Community notification
3. Oracle Dependencies
Design: Token price from GeckoTerminal API.
Mitigation:
- Multiple price sources planned
- Price bounds checking
- Fallback mechanisms
- Manual override capability
4. Cross-Chain Risks
Design: Manual cash out processing.
Mitigation:
- Admin verification
- Refund capability
- Event logging
- User notifications
Attack Vectors & Mitigations
Flash Loan Attacks
Vector: Manipulate positions with borrowed funds.
Mitigation:
- β 60-second cooldown
- β Permanent staking (no instant withdrawals)
- β Time-weighted calculations
- β Minimum stake amounts
Front-Running
Vector: Watch mempool and front-run transactions.
Mitigation:
- β Rate limiting per address
- β Cooldown prevents rapid actions
- β No critical timing dependencies
- β Slippage not applicable (fixed rates)
Sybil Attacks
Vector: Create multiple accounts to game referrals.
Mitigation:
- β Self-referral blocked
- β Minimum stake requirements
- β Volume-based milestones
- β Economic disincentives
Reentrancy
Vector: Recursive calls to drain funds.
Mitigation:
- β ReentrancyGuard on all functions
- β Checks-Effects-Interactions pattern
- β State updates before transfers
- β SafeERC20 usage
Integer Overflow/Underflow
Vector: Arithmetic errors to manipulate balances.
Mitigation:
- β Solidity 0.8+ (built-in overflow checks)
- β SafeMath patterns
- β Proper type sizing
- β Bounds checking
Emergency Procedures
Emergency Withdrawal
bool public emergencyWithdrawEnabled;
function setEmergencyWithdraw(bool _enabled) external onlyOwner {
emergencyWithdrawEnabled = _enabled;
}
function emergencyWithdraw() external nonReentrant {
require(emergencyWithdrawEnabled, "Not enabled");
// Return user's staked amount (no interest, no penalties)
uint256 totalWithdrawable = user.totalStaked;
// Transfer back to user
stakingToken.safeTransfer(msg.sender, totalWithdrawable);
}When Used:
- Critical vulnerability found
- Platform sunset
- Force majeure events
User Impact:
- Recover principal
- No interest paid
- Positions closed
Contract Pause
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}Use Cases:
- Suspicious activity
- Upgrade preparation
- Maintenance window
- Security response
Security Best Practices
For Users
User Security Checklist:
- β Verify contract address
- β Check transaction details before signing
- β Use hardware wallet for large amounts
- β Never share private keys
- β Verify approval amounts
- β Monitor position regularly
- β Enable wallet notifications
- β Keep recovery phrase secure
For Developers
Developer Security Checklist:
- β Validate all inputs
- β Use latest OpenZeppelin contracts
- β Follow Checks-Effects-Interactions
- β Test edge cases thoroughly
- β Monitor events in real-time
- β Implement circuit breakers
- β Document security assumptions
- β Regular security reviews
Audit Status
Smart contract audit in progress.
Audit Scope
- Core staking logic
- Vesting mechanisms
- Referral system
- Access control
- Emergency functions
- Economic model
- Event emission
- Gas optimization
Expected Timeline
- Audit Start: TBD
- Initial Report: TBD
- Fixes Applied: TBD
- Final Report: TBD
Bug Bounty Program
Coming soon: Bug bounty program details.
Planned Rewards
| Severity | Reward Range |
|---|---|
| Critical | 50,000 |
| High | 10,000 |
| Medium | 5,000 |
| Low | 1,000 |
Scope
- Smart contracts
- Frontend vulnerabilities
- Backend API security
- Infrastructure issues
Incident Response
Response Plan
- Detection: Monitoring alerts trigger
- Assessment: Evaluate severity
- Containment: Pause if critical
- Investigation: Determine root cause
- Resolution: Deploy fix
- Communication: Notify users
- Post-Mortem: Document learnings
Communication Channels
- Discord announcements
- Twitter updates
- Email notifications
- Website banner
Security Resources
Documentation
- OpenZeppelin Docs (opens in a new tab)
- Solidity Security (opens in a new tab)
- Smart Contract Best Practices (opens in a new tab)
Tools Used
- Hardhat for testing
- Slither for static analysis
- Mythril for symbolic execution
- Tenderly for monitoring
Responsible Disclosure
Found a vulnerability? Please report responsibly:
π§ Email: security@dogwithcap.xyz
Please Include:
- Detailed description
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
Response Time:
- Acknowledgment: 24 hours
- Initial assessment: 48 hours
- Resolution timeline: Case-dependent
Next Steps
Security is a continuous process, not a destination.
We're committed to maintaining the highest security standards for our users.