Skip to content

noelialuz/StakingApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

5 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿฆ StakingApp

GitHub Repository Solidity Foundry License: MIT

A Foundry-based ERC-20 staking dApp where users lock a fixed token amount and claim ETH rewards after a configurable period.

StakingApp is a learning-oriented smart contract project that demonstrates token staking with time-locked ETH rewards. Users deposit a predefined ERC-20 amount, wait for the staking period to elapse, and claim ETH funded by the contract owner. The owner can fund the contract, adjust the staking period, and manage access through OpenZeppelin's Ownable.

Key features:

  • ๐Ÿ”’ Fixed-amount ERC-20 deposits โ€” one active stake per user
  • โฑ๏ธ Configurable staking period with multi-period reward accrual
  • ๐Ÿ’ฐ ETH reward claims after the lock period
  • ๐Ÿ‘ค Owner-controlled funding via receive() and period updates
  • ๐Ÿ›ก๏ธ SafeERC20 transfers and Checks-Effects-Interactions (CEI) on withdrawals
  • โœ… Full unit test suite (15 tests) covering deposit, withdraw, rewards, and access control

๐Ÿ“‹ Table of Contents

  1. Prerequisites & Dependencies
  2. Technologies & Versions
  3. Project Structure
  4. Quick Start
  5. Running Tests
  6. Cache & Architecture
  7. Security Policy
  8. Scripts & Commands
  9. License
  10. About the Author

๐Ÿ“ฆ Prerequisites & Dependencies

System requirements

Requirement Notes
๐Ÿ–ฅ๏ธ OS macOS, Linux, or Windows (WSL recommended)
๐Ÿฆ€ Foundry Install Foundry โ€” includes forge, cast, and anvil
๐Ÿ”ง Git Required for cloning and managing submodules

Install Foundry:

curl -L https://foundry.paradigm.xyz | bash
foundryup

Verify the installation:

forge --version

Project dependencies

Dependencies are managed as Git submodules under lib/ and pinned in foundry.lock.

Dependency Version Purpose
OpenZeppelin Contracts v5.6.1 ERC20, Ownable, SafeERC20
forge-std v1.16.1 Foundry testing utilities and cheatcodes

Warning

When installing OpenZeppelin via git, avoid tracking the master branch. Use tagged releases (for example @v5.6.1) so builds stay reproducible. See the OpenZeppelin Foundry installation notes.

Install or update dependencies explicitly:

forge install foundry-rs/forge-std@v1.16.1
forge install OpenZeppelin/openzeppelin-contracts@v5.6.1

๐Ÿ›  Technologies & Versions

Technology Version Role
Solidity 0.8.35 Smart contract language
Foundry (forge) 1.7.1+ Build, test, and deploy toolchain
OpenZeppelin Contracts v5.6.1 Battle-tested contract libraries
forge-std v1.16.1 Test helpers, cheatcodes, assertions
Git submodules โ€” Dependency management via lib/

๐Ÿ“ Project Structure

StakingApp/
โ”œโ”€โ”€ ๐Ÿ“‚ src/
โ”‚   โ”œโ”€โ”€ StakingApp.sol        # Main staking logic: deposit, withdraw, claim rewards
โ”‚   โ”œโ”€โ”€ StakingAppv1.sol      # Draft / alternate implementation (WIP)
โ”‚   โ””โ”€โ”€ StakingToken.sol      # Mintable ERC-20 token used for staking
โ”œโ”€โ”€ ๐Ÿ“‚ test/
โ”‚   โ”œโ”€โ”€ StakingAppTest.t.sol  # StakingApp unit tests (14 tests)
โ”‚   โ””โ”€โ”€ StakingTokenTest.t.sol # StakingToken unit tests (1 test)
โ”œโ”€โ”€ ๐Ÿ“‚ lib/
โ”‚   โ”œโ”€โ”€ forge-std/            # Foundry standard library (submodule)
โ”‚   โ””โ”€โ”€ openzeppelin-contracts/ # OpenZeppelin contracts (submodule)
โ”œโ”€โ”€ ๐Ÿ“‚ cache/                 # Foundry compilation cache (auto-generated)
โ”œโ”€โ”€ ๐Ÿ“‚ out/                   # Compiled artifacts & ABIs (auto-generated)
โ”œโ”€โ”€ foundry.toml              # Foundry project configuration
โ”œโ”€โ”€ foundry.lock              # Pinned dependency versions
โ””โ”€โ”€ README.md

๐Ÿš€ Quick Start

1. Clone the repository

git clone https://github.com/noelialuz/StakingApp.git
cd StakingApp

2. Install dependencies

forge install

If submodules are missing, run the explicit install commands from the Prerequisites section.

3. Compile the contracts

forge build

A successful build produces artifacts in out/ and updates the cache in cache/.

4. Run the test suite

forge test

5. Format the code (optional)

forge fmt

Check formatting without modifying files:

forge fmt --check

Usage overview

Deploy StakingToken and StakingApp, then interact with the staking contract:

// 1. Deploy StakingToken and StakingApp with constructor parameters.
// 2. Owner funds StakingApp with ETH (receive is restricted to owner).
// 3. User approves and deposits the fixed staking amount.
// 4. After stakingPeriod elapses, user calls claimRewards().

Example test flow with Foundry cheatcodes:

stakingToken.mint(tokenAmount);
IERC20(stakingToken).approve(address(stakingApp), tokenAmount);
stakingApp.depositTokens(tokenAmount);

vm.warp(block.timestamp + stakingPeriod);
stakingApp.claimRewards();

๐Ÿงช Running Tests

Run all tests

forge test

Expected output includes a summary table:

โ•ญ------------------+--------+--------+---------โ•ฎ
| Test Suite       | Passed | Failed | Skipped |
+==============================================+
| StakingAppTest   | 14     | 0      | 0       |
|------------------+--------+--------+---------|
| StakingTokenTest | 1      | 0      | 0       |
โ•ฐ------------------+--------+--------+---------โ•ฏ

Verbose output

Show logs and traces for each test:

forge test -vvv

Maximum verbosity (stack traces on failure):

forge test -vvvv

Run a specific test file

forge test --match-path test/StakingAppTest.t.sol

Run a single test function

forge test --match-test testDepositTokensCorrectly

Gas report

Generate a gas usage report for all tests:

forge test --gas-report

Test coverage

forge coverage

Test suites covered

Suite Tests Scope
StakingAppTest 14 Deployment, deposits, withdrawals, rewards, owner access, ETH funding
StakingTokenTest 1 Token minting

๐Ÿ—„ Architecture

StakingApp consists of two main contracts and three actor roles:

flowchart TB
    subgraph Contracts
        ST["๐Ÿช™ StakingToken<br/>(ERC-20)"]
        SA["๐Ÿฆ StakingApp<br/>(Ownable)"]
    end

    subgraph Actors
        Owner["๐Ÿ‘ค Owner"]
        User["๐Ÿ‘ค Staker"]
    end

    Owner -->|"fund ETH (receive)"| SA
    Owner -->|"changeStakingPeriod()"| SA
    User -->|"mint()"| ST
    User -->|"approve + depositTokens()"| SA
    SA -->|"safeTransferFrom"| ST
    User -->|"withdrawTokens()"| SA
    SA -->|"safeTransfer"| ST
    User -->|"claimRewards()"| SA
    SA -->|"ETH transfer"| User
Loading

Contract responsibilities

Contract Responsibility
StakingToken Simple mintable ERC-20 token used as the staking asset
StakingApp Holds staked tokens, tracks user balances and lock timestamps, distributes ETH rewards

Core state

Variable Description
stakingToken Address of the ERC-20 token to stake
stakingPeriod Minimum time (seconds) before rewards can be claimed
fixedStakingAmount Exact token amount required per deposit
rewardPerPeriod ETH reward paid per completed staking period
userBalance Active stake amount per user
elapsePeriod Timestamp when the user started or last claimed

User flow

  1. Deposit โ€” User approves and calls depositTokens(fixedStakingAmount). Only one active stake per address.
  2. Wait โ€” Staking period must elapse. Multiple periods accrue proportionally.
  3. Claim โ€” User calls claimRewards() to receive ETH. The elapsed timer advances by claimed periods.
  4. Withdraw โ€” User calls withdrawTokens() to recover staked ERC-20 tokens (CEI pattern applied).

Owner flow

  1. Fund โ€” Owner sends ETH to the contract via receive() (owner-only).
  2. Configure โ€” Owner calls changeStakingPeriod() to update the lock duration.

๐Ÿ” Security Policy

โš ๏ธ This project is intended for learning and demonstration purposes only. It has not undergone a professional security audit.

Known considerations

Area Detail
๐ŸŽ“ Educational scope Not production-ready; use at your own risk
๐Ÿ’ธ Owner trust Owner controls ETH funding and staking period โ€” users must trust the owner
๐Ÿ” Reentrancy Withdrawals follow CEI; reward claims use low-level call โ€” review before mainnet use
๐Ÿช™ Token model StakingToken.mint() is unrestricted โ€” suitable for testing only
๐Ÿ“ฆ Dependencies Keep OpenZeppelin and forge-std on tagged releases aligned with foundry.lock

Before using in production

  • Review staking, withdrawal, and reward logic in src/StakingApp.sol
  • Run the full test suite: forge test
  • Consider a professional audit
  • Restrict token minting and add access controls as needed
  • Keep dependencies pinned to tagged releases

Reporting vulnerabilities

If you discover a security issue, please do not open a public GitHub issue. Contact the repository owner directly (see About the Author).

Smart contracts carry inherent technical and financial risk. Use this repository at your own responsibility.


๐Ÿ“œ Scripts & Commands

This project does not include a script/ deployment folder yet. All operations are performed through Foundry CLI commands:

Command Description
forge build Compile all contracts
forge test Run the full test suite
forge test -vvv Run tests with detailed traces
forge test --gas-report Show gas usage per function
forge coverage Generate test coverage report
forge fmt Format Solidity source files
forge fmt --check Verify formatting (CI-friendly)
forge clean Remove cache/ and out/ artifacts
anvil Start a local Ethereum node for manual testing
cast call <addr> <sig> Read on-chain state from a deployed contract
cast send <addr> <sig> Send a transaction to a deployed contract

Adding deployment scripts

To add deployment automation, create a script/ directory:

mkdir script

Then add a Foundry script (e.g. script/Deploy.s.sol) and run it with:

forge script script/Deploy.s.sol --rpc-url <RPC_URL> --broadcast

๐Ÿ“„ License

StakingApp is released under the MIT License.

SPDX identifiers in source files: // SPDX-License-Identifier: MIT


๐Ÿ‘ค About the Author

Name Noelia Luz Fernรกndez
GitHub @Noelialuz
LinkedIn https://www.linkedin.com/in/noelia-luz-fernandez-03404440/
Email noelia_luz_fernandez@hotmail.com

๐Ÿ“š Learn More

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors