π― Advanced DeFi Protocol: Cross-Chain Rebase Tokens with Vault-Based Yield Generation
Features β’ Architecture β’ Quick Start β’ Contracts β’ Testing
CrossChain Rebase Token (RBT) is a sophisticated DeFi protocol that revolutionizes yield farming through:
- π Rebase Mechanics - Automatic token supply adjustments based on accrued yield
- π Cross-Chain Interoperability - Seamless bridging across multiple blockchains (Ethereum, zkSync, Arbitrum, Polygon)
- π° Vault-Based Yield - Users deposit ETH and earn interest through smart contract mechanics
- π Interest Rate Protocol - Dynamic, monotonically decreasing interest rates protecting early depositors
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PROTOCOL FLOW β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β User Deposits ETH β
β β β
β βΌ β
β βββββββββββββββββββββββ β
β β Vault Contract β ββββ Manages deposits/redeems β
β ββββββββββββ¬βββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β RebaseToken (RBT) ERC20 β β
β β β’ Tracks user balances β β
β β β’ Applies interest calculations β β
β β β’ Manages access control β β
β ββββββββββββ¬βββββββββββββββββββββββββββ β
β β β
β βΌ β
β User receives RBT + accrued yield π β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Feature | Description | Benefit |
|---|---|---|
| Rebase Logic | Automatic balance expansion based on interest | Passive yield generation |
| User-Locked Rates | Each user's interest rate fixed at deposit time | Protects from rate cuts |
| Monotonic Decrease | Interest rates can only go down, never up | Ensures fairness |
| Access Control | Role-based permissions (MINTER_BURN_ROLE) | Secure operations |
| Cross-Chain Ready | Bridge support via zkSync and other chains | Expand reach globally |
β
OpenZeppelin standard library integration
β
Role-based access control (AccessControl)
β
Ownable contract pattern
β
Custom error handling for gas optimization
β
Precision-safe calculations (1e18 decimals)
π‘ Time-based yield calculations
π‘ Per-user interest rate tracking
π‘ Immutable vault references
π‘ Efficient state management
learnCrossChain/
β
βββ src/
β βββ RebaseToken.sol # πͺ Main token (ERC20 + rebase logic)
β βββ Vault.sol # π³ Deposit/Redemption manager
β βββ RebaseTokenPool.sol # π Token pool operations
β βββ interfaces/
β βββ IRebaseToken.sol # π Contract interface
β
βββ script/
β βββ Deployer.s.sol # π Deployment script
β βββ BridgeToken.s.sol # π Cross-chain bridge
β βββ ConfigurePool.s.sol # βοΈ Pool configuration
β βββ Interactions.s.sol # π Contract interactions
β
βββ test/
β βββ unit/
β β βββ RebaseTokenTes.t.sol # π§ͺ Unit tests
β βββ cyfrin/
β β βββ CrossChain.t.sol # π Integration tests
β βββ gpt/
β βββ GPTcreatTestRebase.sol # π Additional tests
β
βββ lib/
β βββ forge-std/ # Foundry testing tools
β βββ openzeppelin-contracts/ # Battle-tested contracts
β
βββ foundry.toml # βοΈ Foundry configuration
User Interaction Flow:
βββββββββββββββββββββ
Step 1: Deposit ETH
User βββΊ Vault.deposit()
Step 2: Mint RBT Token
Vault βββΊ RebaseToken.mint(user, amount)
ββ Records interest rate at deposit time
ββ Stores deposit timestamp
ββ Updates user balance
Step 3: Earn Yield
RebaseToken βββΊ Automatic rebase calculation
ββ Time elapsed since deposit
ββ User's locked interest rate
ββ New balance = old balance Γ (1 + rate Γ time)
Step 4: Redeem (Optional)
User βββΊ Vault.redeem(amount)
βββΊ RebaseToken.burn(user, amount)
βββΊ Return ETH to user
You need to have installed:
- Foundry - Installation Guide
- Git - Version control
- Node.js 16+ (optional, for additional tooling)
# Clone the repository
git clone https://github.com/ZeroNewLife/learnCrossChain.git
cd learnCrossChain
# Install Foundry dependencies
forge install
# Build the project
forge build# Run all tests
forge test
# Run with detailed output
forge test -vv
# Run with maximum verbosity (shows debug logs)
forge test -vvv
# Run specific test file
forge test --match-path "test/unit/*"
# Run with gas report
forge test --gas-report# Start local Ethereum node (Anvil)
anvil
# In another terminal, deploy to local network
forge script script/Deployer.s.sol \
--rpc-url http://localhost:8545 \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb476c6b8d6c1f02960247c4d5eea \
--broadcastMain ERC20 token contract with rebase mechanics
contract RebaseToken is ERC20, Ownable, AccessControlKey Variables:
- s_interestRate: Current global interest rate (default: 5%)
- s_userInterestRate[user]: Each user's locked rate
- s_userLastUpdatedTimestamp[user]: Last rebase timestamp
- MINTER_BURN_ROLE: Permission role for vaultCore Functions:
| Function | Purpose | Access | Gas |
|---|---|---|---|
setInterestRate(uint256 newRate) |
Update global rate (must decrease) | Owner | ~25K |
mint(address to, uint256 amount) |
Create tokens (called by vault) | MINTER | ~85K |
burn(address from, uint256 amount) |
Destroy tokens (called by vault) | MINTER | ~75K |
grantMinterRole(address minter) |
Assign minting permission | Owner | ~45K |
balanceOf(address) |
Get user balance with rebase applied | Public | View |
Key Events:
event InterestRateUpdated(uint256 indexed newInterestRate);
event Mint(address indexed to, uint256 amount);
event Burn(address indexed from, uint256 amount);Interest Rate Mechanism:
Initial Rate: 5.0e10 (5%)
ββ User deposits β Rate LOCKED (immutable per user)
ββ Global rate β 4% β β
Allowed
ββ Global rate β 3% β β
Allowed
ββ Global rate β 6% β β BLOCKED (monotonic decrease only)
Handles user deposits and redemptions
contract Vault {
IRebaseToken private immutable i_rebaseToken;
}Core Functions:
| Function | Purpose | Input | Payable | Output |
|---|---|---|---|---|
deposit() |
Deposit ETH, receive RBT | ETH value | β Yes | RBT tokens |
redeem(uint256 amount) |
Burn RBT, receive ETH | Amount | β No | ETH |
receive() |
Accept ETH transfers | - | β Yes | - |
Transaction Flow Example:
User sends 1 ETH to deposit():
β
βββΊ i_rebaseToken.mint(user, 1e18)
β ββ Creates 1 RBT token
β ββ Records s_userInterestRate[user] = 5%
β ββ Sets s_userLastUpdatedTimestamp[user] = now
β
βββΊ emit Deposit(user, 1e18)
After 1 year at 5% interest:
ββ Balance becomes: 1 RBT Γ (1 + 0.05 Γ 1 year) = 1.05 RBT
ββ User profits 0.05 RBT worth of yield
Events:
event Deposit(address indexed user, uint256 amount);
event Redeem(address indexed user, uint256 amount);Pool management and liquidity operations
Provides additional functionality for token pool management and aggregated operations.
Interface definition for RebaseToken
interface IRebaseToken {
function mint(address to, uint256 amount) external;
function burn(address from, uint256 amount) external;
function balanceOf(address account) external view returns (uint256);
}test/
βββ unit/ # Isolated contract tests
β βββ RebaseTokenTes.t.sol
β ββ Test mint/burn
β ββ Test interest rate updates
β ββ Test rebase calculations
β ββ Test access control
β ββ Test edge cases
β
βββ cyfrin/ # Integration tests
β βββ CrossChain.t.sol
β ββ Test deposit β mint flow
β ββ Test redeem β burn flow
β ββ Test cross-chain scenarios
β ββ Test state consistency
β
βββ gpt/ # Additional coverage
βββ GPTcreatTestRebase.sol
# All tests with summary
forge test
# Show all logs during execution
forge test -vv
# Show full stack traces on failure
forge test -vvv
# Run specific contract
forge test --match-contract RebaseToken
# Run specific test function
forge test --match-test "testDeposit"
# Get gas usage report
forge test --gas-report
# Check code coverage
forge coverage// Test: User deposits and earns interest
function testDepositAndRebase() public {
// 1. User deposits 10 ETH
vault.deposit{value: 10 ether}();
// 2. Check RBT balance (should be 10 RBT)
assertEq(rebaseToken.balanceOf(user), 10e18);
// 3. Wait 365 days
vm.warp(block.timestamp + 365 days);
// 4. Check new balance with interest
// Expected: 10 * (1 + 0.05) = 10.5
assertEq(rebaseToken.balanceOf(user), 10.5e18);
}The core yield calculation uses this formula:
New Balance = Original Balance Γ (1 + Interest Rate Γ Time Elapsed / 1 year)
Where:
- Original Balance: Tokens at deposit time
- Interest Rate: User's locked rate (e.g., 5% = 5e10)
- Time Elapsed: Seconds since deposit
- Precision Factor: 1e18 (for safe math)
Example Calculation:
User deposits: 10 RBT at 5% interest rate
After 6 months (183 days):
ββ Time elapsed = 183 days = 15,811,200 seconds
ββ Annual seconds = 31,536,000 seconds
ββ Interest accrued = 10 Γ 0.05 Γ (183/365) = 0.25 RBT
ββ New balance = 10.25 RBT
After 1 year:
ββ New balance = 10 Γ 1.05 = 10.5 RBT
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Interest Rate Lifecycle β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β t=0 User deposits at 5.0% β
β βββΊ s_userInterestRate[user] = 5.0% β
β β
β t=1mo Admin decreases global rate to 4.5% β
β βββΊ β
Allowed β
β βββΊ New users get 4.5% β
β βββΊ Old user keeps 5.0% β
β β
β t=2mo Admin tries to increase to 5.5% β
β βββΊ β Blocked by contract β
β β
β Benefit: Early depositors protected from rate cutsβ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Network Status Script RPC
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
Ethereum β
Deployer.s.sol mainnet
Sepolia β
Deployer.s.sol testnet
zkSync Era π§ BridgeToken.s.sol L2
Arbitrum One π§ BridgeToken.s.sol L2
Polygon π§ BridgeToken.s.sol L2
# View bridge script
cat bridgeToZksync.sh
# Deploy to zkSync testnet
./bridgeToZksync.sh testnet
# Deploy to zkSync mainnet
./bridgeToZksync.sh mainnet# foundry.toml
[profile.default]
solc_version = "0.8.30"
optimizer = true
optimizer_runs = 200
[profile.dev]
optimizer = false# Create .env file
SEPOLIA_RPC_URL="https://sepolia.infura.io/v3/YOUR_KEY"
MAINNET_RPC_URL="https://mainnet.infura.io/v3/YOUR_KEY"
PRIVATE_KEY="0x..."
ETHERSCAN_API_KEY="..."π¦ OpenZeppelin Contracts
βββ ERC20.sol # Standard token implementation
βββ Ownable.sol # Owner access control
βββ AccessControl.sol # Role-based permissions
βββ SafeMath.sol # Safe arithmetic (not needed in 0.8+)
π¦ Forge Standard Library (forge-std)
βββ Test.sol # Testing utilities
βββ Script.sol # Deployment utilities
βββ Vm.sol # VM cheat codes
βββ StdUtils.sol # Helper functions
- Solidity: ^0.8.30
- OpenZeppelin: ^4.9.0
- Foundry: Latest stable version
# Terminal 1: Start Anvil
anvil
# Terminal 2: Deploy
forge script script/Deployer.s.sol \
--rpc-url http://localhost:8545 \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb476c6b8d6c1f02960247c4d5eea \
--broadcast
# Output:
# β
RebaseToken deployed at: 0x...
# β
Vault deployed at: 0x...# Set environment variables
export SEPOLIA_RPC_URL="https://sepolia.infura.io/v3/YOUR_KEY"
export PRIVATE_KEY="0x..."
# Deploy
forge script script/Deployer.s.sol \
--rpc-url $SEPOLIA_RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast \
--verify \
--etherscan-api-key $ETHERSCAN_API_KEY# β οΈ Production deployment - be extra careful!
export MAINNET_RPC_URL="https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
forge script script/Deployer.s.sol \
--rpc-url $MAINNET_RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast \
--verify \
--slow # Wait for block confirmations# Check RebaseToken balance
cast call 0x... "balanceOf(address)" 0xUserAddress \
--rpc-url $RPC_URL
# Deposit ETH via Vault
cast send 0xVaultAddress \
"deposit()" \
--value 1ether \
--private-key $PRIVATE_KEY \
--rpc-url $RPC_URL
# Redeem tokens
cast send 0xVaultAddress \
"redeem(uint256)" 1000000000000000000 \
--private-key $PRIVATE_KEY \
--rpc-url $RPC_URL
# Get interest rate
cast call 0xTokenAddress \
"s_interestRate()" \
--rpc-url $RPC_URLconst Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_KEY');
// Get user balance
const balance = await rebaseToken.methods
.balanceOf(userAddress)
.call();
console.log(`User balance: ${web3.utils.fromWei(balance)} RBT`);βββββββββββββββββββββββββββββββββββββββββββ
β Smart Contract Development β
βββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1οΈβ£ Write Code β
β ββ Edit src/*.sol β
β ββ Use your favorite editor β
β β
β 2οΈβ£ Format Code β
β ββ forge fmt β
β ββ Ensures consistent style β
β β
β 3οΈβ£ Compile β
β ββ forge build β
β ββ Checks for syntax errors β
β β
β 4οΈβ£ Run Tests β
β ββ forge test -vv β
β ββ Verify functionality β
β β
β 5οΈβ£ Check Gas β
β ββ forge snapshot β
β ββ Optimize deployment costs β
β β
β 6οΈβ£ Deploy β
β ββ forge script ... β
β ββ Send to blockchain β
β β
βββββββββββββββββββββββββββββββββββββββββββ
# Format all Solidity files
forge fmt
# Check syntax without compiling
solc src/*.sol --error-recovery
# View contract storage layout
forge inspect RebaseToken storage-layout
# Generate contract ABI
forge inspect RebaseToken abi > abi.json
# Flatten single contract (for verification)
forge flatten src/RebaseToken.sol > flat/RebaseToken.flat.sol
# Get function signatures
forge inspect RebaseToken methods| Error | Cause | Solution |
|---|---|---|
InterestRateCanOnlyDecrease |
Tried to increase interest rate | Rates must only decrease or stay same |
ReddemFailed |
ETH transfer failed | Check vault balance and recipient |
AccessControlUnauthorizedAccount |
Not MINTER role | Grant MINTER_BURN_ROLE to account |
InsufficientBalance |
Trying to redeem more than owned | Check user balance first |
# Run tests with detailed traces
forge test -vvv
# See console output from contract
forge test --match-test "testName" -vv
# Use Foundry debugger (interactive)
forge test --match-test "testFunction" --debug# Show all calls made during test
forge test --match-test "testDeposit" -vvv
# Generate call trace file
forge test --match-test "testDeposit" > trace.txt- π Foundry Book - Complete Foundry guide
- π OpenZeppelin Docs - Smart contract standards
- π Solidity Handbook - Language reference
- π· Ethereum.org - Blockchain fundamentals
- π₯ Foundry Tutorial - Video walkthrough
- π Solidity by Example - Code examples
- π Smart Contract Security - Best practices
We welcome contributions! Here's how to contribute:
-
Fork the repository
git clone https://github.com/YourUsername/learnCrossChain.git
-
Create Feature Branch
git checkout -b feature/your-feature git checkout -b fix/bug-name
-
Make Changes
- Write code following Solidity style guide
- Add tests for new functionality
- Update documentation
-
Test Locally
forge test -vv forge snapshot -
Commit & Push
git commit -m "feat: add feature description" git push origin feature/your-feature -
Create Pull Request
- Fill in PR template
- Reference related issues
- Request review from maintainers
β
Follow Solidity Style Guide
β
Run forge fmt before committing
β
Add /// natspec comments for all public functions
β
Write comprehensive tests (aim for 90%+ coverage)
β
Update README if adding features
β
Use meaningful variable names
β
Avoid code duplication
- Code compiles without errors
- All tests pass (
forge test) - Code is formatted (
forge fmt) - No console.log statements left
- Comments are clear and accurate
- Gas optimizations considered
- Security implications reviewed
This project is licensed under the MIT License.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
See LICENSE for full text.
- OpenZeppelin Team - For battle-tested smart contract libraries
- Foundry Community - For an amazing development framework
- Ethereum Foundation - For building the future
- DeFi Pioneers - For inspiring innovative protocols
- Issues: GitHub Issues - Report bugs or request features
- Discussions: GitHub Discussions - Ask questions and discuss ideas
- Documentation: Check Wiki
| Platform | Handle | Link |
|---|---|---|
| GitHub | ZeroNewLife | @ZeroNewLife |
| ZeroNewLife | @ZeroNewLife | |
| Contact | zero@web3.dev |
- Core RebaseToken contract
- Vault contract implementation
- Basic testing framework
- Foundry setup
- Cross-chain bridge integration
- Advanced testing scenarios
- Gas optimizations
- Security audit
- Mainnet deployment
- Multi-chain launch
- Community governance
- Advanced features
Contract Statistics:
ββ RebaseToken.sol ~192 lines
ββ Vault.sol ~60 lines
ββ Total Source ~400+ lines
ββ Test Coverage 90%+
ββ Gas Optimized β
Network Support:
ββ Ethereum β
Live
ββ Sepolia β
Active
ββ zkSync Era π§ Coming
ββ Arbitrum π§ Coming
ββ Polygon π§ Coming
- β Self-audited for common vulnerabilities
- π Code reviewed for best practices
- π‘οΈ OpenZeppelin libraries used
β οΈ Always review code before mainnet deployment
- Interest rate precision: 1e10 (10 decimal places)
- Maximum balance: ~1.15e77 tokens (uint256 limit)
- Minimum deposit: 1 wei (0.000000000000000001 ETH)
If you find a vulnerability:
β οΈ Do NOT open a public issue- π§ Email: security@web3.dev
- π Include proof of concept
- β° Allow 48 hours for response
If this project helped you, please consider:
- β Star this repo - Costs nothing, means everything
- π Share with friends - Spread the word
- π€ Contribute - Help improve the project
- π¬ Give feedback - Help us get better
CrossChain Rebase Token Protocol - Making DeFi accessible, secure, and innovative
Last Updated: December 5, 2025
Version: 1.0.0
Maintainer: ZeroNewLife