A cross-chain rebase token implementation using Chainlink CCIP (Cross-Chain Interoperability Protocol) that incentivizes users to deposit ETH in a vault for interest/rewards. The token accrues linear interest over time, and users can bridge their tokens across chains while preserving their interest rate.
- Rebase Token with Interest: Tokens accrue linear interest over time based on a user-specific interest rate
- Cross-Chain Bridging: Bridge tokens between chains (e.g., Sepolia ↔ Arbitrum Sepolia) using Chainlink CCIP
- Interest Rate Preservation: When bridging, users maintain their original interest rate from the source chain
- Decreasing Global Interest Rate: The protocol rewards early users with higher interest rates
- Vault Integration: Deposit ETH to receive rebase tokens, redeem tokens to withdraw ETH
- Clone the repository:
git clone git@github.com:Adeshh/ccip-rebase-token.git
cd ccip-rebase-token- Install dependencies:
forge install- Build the project:
forge buildccip-rebase-token/
├── src/
│ ├── RebaseToken.sol # Main rebase token contract with interest accrual
│ ├── RebaseTokenPool.sol # CCIP token pool for cross-chain bridging
│ ├── Vault.sol # Vault contract for ETH deposits/redemptions
│ └── interfaces/
│ └── IRebaseToken.sol # Interface for RebaseToken
├── test/
│ ├── RebaseToken.t.sol # Unit tests for RebaseToken
│ └── CrossChain.t.sol # Cross-chain integration tests
├── script/
│ ├── Deployer.s.sol # Deployment scripts
│ ├── ConfigurePool.s.sol # Pool configuration scripts
│ ├── BridgeTokens.s.sol # Token bridging scripts
│ └── Interactions.s.sol # Interaction scripts
└── lib/ # Dependencies (CCIP, OpenZeppelin, Chainlink Local)
- Global Interest Rate: Starts at
5e10per second and can only decrease - User Interest Rate: Set when a user first receives tokens (via deposit or transfer)
- Linear Interest: Interest accrues linearly over time:
balance = principle * (1 + rate * time) - Interest Preservation: When bridging, the user's interest rate is preserved and sent to the destination chain
- Lock & Burn: On the source chain, tokens are burned and the user's interest rate is encoded in
destPoolData - Release & Mint: On the destination chain, tokens are minted with the preserved interest rate
- CCIP Integration: Uses Chainlink CCIP for secure, verified cross-chain messaging
forge test# Unit tests only
forge test --match-contract RebaseTokenTest
# Cross-chain tests only
forge test --match-contract CrossChainTestCross-chain tests require RPC access to Sepolia and Arbitrum Sepolia networks. Configure RPC URLs in foundry.toml or use environment variables:
export SEPOLIA_RPC_URL="your-sepolia-rpc-url"
export ARB_SEPOLIA_RPC_URL="your-arbitrum-sepolia-rpc-url"
forge test --match-test testBridgeAllTokensforge coverage// User deposits ETH into vault
vault.deposit{value: 1 ether}();
// User receives rebase tokens with current global interest rate
uint256 balance = rebaseToken.balanceOf(user);
uint256 interestRate = rebaseToken.getUserIntrestRate(user);// Approve router to spend tokens
IERC20(token).approve(routerAddress, amount);
// Create CCIP message
Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
receiver: abi.encode(user),
data: "",
tokenAmounts: tokenAmounts,
feeToken: linkAddress,
extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 300_000}))
});
// Send cross-chain message
IRouterClient(routerAddress).ccipSend(destinationChainSelector, message);// Redeem all tokens
vault.redeem(type(uint256).max);
// Or redeem specific amount
vault.redeem(amount);- Start a local Anvil node:
anvil- Deploy contracts:
forge script script/Deployer.s.sol:TokenAndPoolDeployer --rpc-url http://localhost:8545 --broadcast- Set up environment variables:
export PRIVATE_KEY="your-private-key"
export SEPOLIA_RPC_URL="your-sepolia-rpc-url"
export ARB_SEPOLIA_RPC_URL="your-arbitrum-sepolia-rpc-url"- Deploy to Sepolia:
forge script script/Deployer.s.sol:TokenAndPoolDeployer --rpc-url $SEPOLIA_RPC_URL --broadcast --verify- Configure pools for cross-chain:
forge script script/ConfigurePool.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcast- Access Control: Only authorized addresses (with
MINT_AND_BURN_ROLE) can mint/burn tokens - Interest Rate: Global interest rate can only decrease, preventing manipulation
- CCIP Security: Leverages Chainlink's battle-tested CCIP protocol for cross-chain messaging
- Rate Limiting: Token pools support rate limiting for additional security
- Inherits:
ERC20,Ownable,AccessControl - Key Functions:
mint(): Mint tokens with a specific interest rateburn(): Burn tokens from a userbalanceOf(): Get balance including accrued interestprincipleBalanceOf(): Get balance without interestgetUserIntrestRate(): Get user's interest ratesetIntrestRate(): Owner can decrease global interest rate
- Inherits:
TokenPool(CCIP) - Key Functions:
lockOrBurn(): Burn tokens and encode interest rate for cross-chain transferreleaseOrMint(): Mint tokens on destination chain with preserved interest rate
- Key Functions:
deposit(): Deposit ETH and receive rebase tokensredeem(): Redeem rebase tokens for ETH