Skip to content

Security: BuildsWithKing/king-yield-aggregator

Security

docs/SECURITY.md

Security Policy

Overview

King Yield Aggregator (KYA) is a learning project with 100% test coverage. While significant effort has been made to follow best practices, this code has NOT been professionally audited and should not be used with real funds on mainnet without proper security review.


Table of Contents


Audit Status

Status Details
Professional Audit ❌ Not conducted
Static Analysis ✅ Aderyn (high-severity findings addressed)
Test Coverage ✅ 100% lines, statements, branches, functions
Fuzz Testing ✅ Deposit/withdraw scenarios
Mainnet Deployment ❌ Not recommended without audit
Last Review December 2025

Recommendation: Do NOT use this code in production without:

  1. Professional security audit ($30k-80k)
  2. Bug bounty program ($10k+ rewards)
  3. Staged rollout (testnet → limited mainnet → full)
  4. Insurance coverage

Known Risks

🔴 Critical Risks

1. Strategy Contract Risk

Risk: Malicious or buggy strategy can drain all deposited funds

Scenario:

// Malicious strategy
function withdraw(uint256 amount) external {
    // Instead of returning funds, sends to attacker
    token.transfer(ATTACKER, token.balanceOf(address(this)));
}

Impact: Total loss of funds in that strategy

Mitigation:

  • ✅ Only King/Admin can add strategies (trust assumption)
  • ❌ No strategy whitelist or verification
  • ❌ No withdrawal limits per strategy
  • ❌ No timelock on strategy changes

User Protection: None currently. Users trust King/Admin.


2. Admin Key Compromise

Risk: If Admin private key is stolen, attacker can switch to malicious strategy

Scenario:

  1. Attacker steals Admin key
  2. Deploys malicious strategy
  3. Calls addStrategy(maliciousStrategy)
  4. Calls setActiveStrategy(maliciousId)
  5. All new deposits go to malicious strategy

Impact: All future deposits stolen

Mitigation:

  • ✅ King can revoke Admin via assignAdmin()
  • ❌ No timelock on strategy changes (instant)
  • ❌ No multi-sig requirement
  • ❌ No monitoring alerts

User Protection: King must notice and react quickly.


3. Underlying Protocol Exploit

Risk: If Aave, Compound, or other integrated protocol is hacked, user funds are lost

Scenario:

  • Aave has a critical vulnerability
  • Attacker drains all Aave pools
  • KYA's deposited funds in Aave are gone

Impact: Partial or total loss depending on deployment %

Mitigation:

  • ❌ No insurance coverage
  • ❌ No circuit breakers

User Protection: None. Users inherit protocol risk.


4. Reentrancy on Malicious Tokens

Risk: ERC777 or malicious ERC20 can callback during transfer

Scenario:

// Malicious token
function transferFrom(address from, address to, uint256 amount) {
    // Callback to VaultCore.deposit() again
    VaultCore(to).deposit(amount);
    // Now state is inconsistent
}

Impact: Double-counting shares, draining vault

Mitigation:

  • nonReentrant modifier on deposit/withdraw
  • ✅ Checks-Effects-Interactions pattern
  • ❌ No token whitelist

User Protection: Only use vetted ERC20 tokens (USDC, DAI, etc.)


🟡 High Risks

4. Share Inflation Attack (First Depositor Attack) ⚠️ MITIGATED

Risk: Attacker can manipulate share price to steal from second depositor

Attack Requirements:

  1. Vault must be completely empty (0 shares)
  2. Attacker must front-run the first legitimate deposit
  3. Attacker must be willing to donate significant funds to inflate price

How the attack would work (if no protection existed):

  1. Attacker deposits 1 wei → receives 1 share
  2. Attacker transfers 1M tokens DIRECTLY to vault (bypasses deposit)
  3. Share price inflates to: 1M tokens per share
  4. Victim deposits 2M tokens → receives only ~1 share (rounds down)
  5. Attacker withdraws 1 share → gets 1.5M tokens (500k profit)
  6. Victim withdraws 1 share → gets 1.5M tokens (500k loss)

Current Protection:

// VaultCore.sol
uint256 public immutable i_minimumFirstDeposit;

constructor(address _king, address _admin, address _asset) {
    uint8 decimals = IERC20Metadata(_asset).decimals();
    i_minimumFirstDeposit = 10 ** decimals; // 1 full token
}

// In deposit():
if (totalSharesBefore == 0 || tAssetsBefore == 0) {
    if(actualReceived < i_minimumFirstDeposit) {
        revert MinimumDepositNotMet(actualReceived, i_minimumFirstDeposit);
    }
    mintedShares = actualReceived;
}

Protection details:

  • Minimum first deposit: 1 full token
    • USDC (6 decimals): $1 minimum
    • DAI (18 decimals): 1 DAI minimum
    • WBTC (8 decimals): 1 BTC minimum (~$100k)
  • ✅ Calculated dynamically based on token decimals
  • ✅ Makes attack significantly more expensive and reduces feasibility

Attack cost with protection:

  • Attacker must deposit: $1 (for USDC)
  • Attacker must donate: ~$1M to make attack profitable
  • Total capital at risk: ~$1M
  • Expected profit: ~$500k
  • Not economically rational for most scenarios

Remaining risk:

  • ⚠️ Well-funded attacker could still execute (needs $1M+ capital)
  • ⚠️ Attack becomes profitable only with large victim deposits ($2M+)
  • ❌ No virtual shares offset (ERC4626 additional protection)

Mitigation status:

  • ✅ Minimum deposit implemented
  • ✅ Dynamic calculation (works for all tokens)
  • ⚠️ Partial protection (raises attack cost significantly)
  • ⚠️ Still theoretically vulnerable to wealthy attackers

User Protection:

  • System automatically enforces minimum
  • Attack cost raised from $0.01 to $500k+
  • Risk highest for brand new vaults
  • Recommended: Wait until TVL > $10k before large deposits

5. Front-Running / Sandwich Attacks

Risk: MEV bots can sandwich large deposits/withdrawals

Scenario:

1. User submits deposit of 1M USDC
2. MEV bot sees pending tx
3. Bot deposits 1 wei, donates 100k USDC (inflates share price)
4. User's deposit executes (gets fewer shares than expected)
5. Bot withdraws with profit

Impact: Users get worse share price than expected

Mitigation:

  • ❌ No slippage protection
  • ❌ No minimum shares output parameter
  • ❌ No deadline parameter

User Protection: Use private RPC (Flashbots) for large txs


🟠 Medium Risks

6. Rounding Errors

Risk: Integer division can cause precision loss

Scenario:

shares = (amount * s_totalShares) / totalAssets();
// If amount is small relative to totalAssets, shares rounds to 0

Impact: Dust amounts lost to rounding

Mitigation:

  • ZeroAmount check prevents 0 deposits
  • ⚠️ Small deposits still lose precision

User Protection: Don't deposit tiny amounts (< $10)


7. Gas Griefing

Risk: Attacker can make withdrawals expensive

Scenario:

1. Attacker deposits/withdraws 1000 times
2. Creates 1000 small share balances
3. Legitimate user withdraws
4. Vault must calculate over 1000 shares (gas bomb)

Impact: Withdrawals become too expensive

Mitigation:

  • ✅ Per-user mapping (O(1) lookups)
  • ❌ No max users limit

User Protection: None needed - architecture prevents this


8. Strategy Failure to Withdraw

Risk: Strategy reverts on withdrawal, locking funds

Scenario:

// Buggy strategy
function withdraw(uint256 amount) external {
    require(false, "Oops");  // Always reverts
}

Impact: Funds locked in strategy until fixed

Mitigation:

  • ⚠️ Transaction reverts (user knows immediately)
  • emergencyWithdrawAll() function exists (vault can pull all funds)
  • ❌ No partial withdrawal fallback
  • ✅ Only vault can call emergency function

User Protection: Vault King/Admin can use emergencyWithdrawAll() to recover funds back to the vault, then remove broken strategy


🟢 Low Risks

10. Timestamp Manipulation

Risk: Miners can manipulate block.timestamp by ~15 seconds

Impact: Minimal - only affects rebalance cooldown

Mitigation: Cooldown is 1 hours (15 sec variance negligible)


11. Denial of Service (DoS)

Risk: Attacker spams transactions to clog network

Impact: Users can't deposit/withdraw temporarily

Mitigation: Network-level issue, not contract-specific


Threat Model

Adversaries

Actor Capabilities Motivation
Malicious User Can call any public function Steal funds, grief others
MEV Bot Front-run transactions Extract value from price slippage
Compromised Admin Can add/remove strategies Drain vault via malicious strategy
Malicious Strategy Full control of deployed funds Steal all deposited tokens
Nation State Can censor transactions Block withdrawals (censorship)

Attack Surfaces

┌─────────────────────────────────────────┐
│           USER INTERACTIONS             │
│  - deposit()         [PROTECTED]        │
│  - withdraw()        [PROTECTED]        │
│  - withdrawAll()     [PROTECTED]        │
└───────────────┬─────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────┐
│        ADMIN INTERACTIONS               │
│  - addStrategy()     [TRUST REQUIRED]   │
│  - removeStrategy()  [TRUST REQUIRED]   │
│  - setActiveStrategy()[TRUST REQUIRED]  │
└───────────────┬─────────────────────────┘
                │
                ▼
┌─────────────────────────────────────────┐
│       EXTERNAL CONTRACTS                │
│  - ERC20 Token       [TRUST REQUIRED]   │
│  - Strategy          [TRUST REQUIRED]   │
│  - Underlying Protocol[TRUST REQUIRED]  │
└─────────────────────────────────────────┘

Most Critical: Admin role and Strategy contracts (no trustless guarantees)


Security Measures Implemented

✅ Code-Level Protections

  1. Reentrancy Guards

    • nonReentrant on all deposit/withdraw functions
    • Prevents recursive calls during token transfers
  2. Checks-Effects-Interactions (CEI)

    • State updates before external calls
    • Prevents reentrancy and state inconsistency
  3. Access Control

    • King-only functions for critical operations
    • Admin role for operational tasks
    • Separation of concerns
  4. Input Validation

    • Zero checks on amounts and addresses
    • Share balance validation
    • Strategy existence checks
  5. Custom Errors

    • Gas-efficient error messages
    • Clear failure reasons
  6. Immutable References

    • Asset and IStrategyManagerRebalancer's addresses can't change
    • Prevents malicious upgrades
  7. Event Emissions

    • All state changes emit events
    • On-chain audit trail
  8. Emergency Functions

    • emergencyWithdrawAll() in StrategyManager
    • Vault can recover funds from broken strategies
    • Only callable by vault (not arbitrary users)
  9. Pausability

    • whenActive modifier on all critical functions
    • King/Admin can pause during emergencies
    • Prevents deposits/withdrawals during exploits
  10. Rebalance Protection

    • 1-hour minimum interval between rebalances
    • Status lock prevents concurrent rebalances
    • Only authorized rebalancer can trigger
  11. Strategy Validation

    • Cannot add zero address as strategy
    • Cannot add same strategy twice
    • Cannot remove strategy with deployed funds

✅ Testing Coverage

  • 100% line coverage
  • 100% branch coverage
  • 100% function coverage
  • Fuzz testing on deposit/withdraw
  • Edge case testing (bad tokens, zero amounts, reentrancy)
  • Integration tests with mock strategies

✅ Documentation

  • Comprehensive NatSpec comments
  • Architecture documentation
  • Usage guides
  • This security policy

Outstanding Security TODOs

Before Testnet Deployment

  • Implement strategy withdrawal limits
  • Add slippage protection to deposit/withdraw
  • Add deadline parameters to prevent stale transactions
  • Create multisig for King role

Before Mainnet Deployment

  • Professional security audit (Trail of Bits, OpenZeppelin, etc.)
  • Bug bounty program (Immunefi, Code4rena)
  • Formal verification of critical functions
  • Timelock on strategy changes (24-48 hour delay)
  • Strategy whitelist with governance
  • Insurance coverage (Nexus Mutual, etc.)
  • Gradual TVL ramp with caps
  • Circuit breakers for rapid TVL changes
  • Emergency governance procedures

Future Enhancements

  • Upgradeable proxy pattern with timelock
  • Decentralized governance (token voting)
  • Multi-strategy allocation (split funds across Aave + Compound)
  • Automated keeper network for rebalancing
  • Cross-chain deployment considerations
  • MEV protection via private RPC
  • Rate limiting on deposits/withdrawals

Responsible Disclosure

If you discover a security vulnerability in KYA, please DO NOT open a public GitHub issue.

Reporting Process

Email: buildswithking@gmail.com

Include:

  1. Detailed description of the vulnerability
  2. Steps to reproduce
  3. Potential impact assessment
  4. Suggested fix (if any)

Response Timeline:

  • Initial response: Within 48 hours
  • Assessment: Within 7 days
  • Fix deployment: Depends on severity

Severity Levels:

  • Critical: Can steal funds or brick contract (fix within 24 hours)
  • High: Can cause loss but requires specific conditions (fix within 7 days)
  • Medium: Limited impact or requires unlikely conditions (fix within 30 days)
  • Low: Informational or edge case (fix in next update)

Bug Bounty Program

Current Status: ❌ No active bug bounty


Disclaimer

USE AT YOUR OWN RISK

This software is provided "as is" without warranty of any kind. By using KYA, you acknowledge:

  1. ✅ You understand smart contract risks
  2. ✅ You understand DeFi protocol risks
  3. ✅ This code is NOT audited
  4. ✅ You could lose all deposited funds
  5. ✅ The developer is not liable for losses
  6. ✅ You have read and understood this security policy

Recommended: Only use with funds you can afford to lose entirely.


Security Checklist for Users

Before depositing funds, verify:

  • You're using the correct contract address
  • The asset token is legitimate (USDC, DAI, etc.)
  • Current active strategy is a known protocol
  • Total Value Locked (TVL) is > $100k (safety in numbers)
  • No recent strategy changes (check events)
  • King/Admin addresses are multisig or known entities
  • You understand worst-case loss is 100%

Contact


Last Updated: December 21, 2025
Version: 1.0.0
Audit Status: Not Audited


Additional Resources


Remember: Security is a journey, not a destination. This document will be updated as the project evolves.

There aren't any published security advisories