-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ab99d8
commit 00f1b58
Showing
1 changed file
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.25; | ||
|
||
import "forge-std/Test.sol"; | ||
|
||
import "../src/extensions/AssetVault.sol"; | ||
|
||
import "../src/interfaces/IAssetToken.sol"; | ||
import "../src/interfaces/IAssetVault.sol"; | ||
import "../src/token/AssetToken.sol"; | ||
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
|
||
// Mock YieldCurrency ERC20 for testing | ||
contract YieldCurrency is ERC20, Ownable { | ||
|
||
constructor(string memory name, string memory symbol, address owner) ERC20(name, symbol) Ownable(owner) { } | ||
|
||
function mint(address account, uint256 amount) public onlyOwner { | ||
_mint(account, amount); | ||
} | ||
|
||
} | ||
|
||
contract AssetVaultTest is Test { | ||
|
||
YieldCurrency public yieldCurrency; | ||
AssetVault public assetVault; | ||
AssetToken public assetToken; | ||
|
||
address public constant OWNER = address(1); | ||
address public constant HOLDER_1 = address(2); | ||
address public constant HOLDER_2 = address(3); | ||
uint256 initialSupply = 1000; | ||
|
||
function setUp() public { | ||
// Setup mock ERC20 YieldCurrency and AssetToken | ||
yieldCurrency = new YieldCurrency("USDC", "USDC", OWNER); | ||
assetToken = new AssetToken( | ||
OWNER, // Address of the owner | ||
"AssetToken", // Name of the token | ||
"AT", // Symbol of the token | ||
yieldCurrency, // ERC20 currency token | ||
18, // Decimals for the asset token | ||
"uri://asset", // Token URI | ||
initialSupply, // Initial supply of AssetToken | ||
1_000_000 // Total value of all AssetTokens | ||
); | ||
// Deploy AssetVault as if it was deployed by a wallet (the `wallet` in AssetVault is set to the deployer) | ||
vm.prank(OWNER); // Ensure the OWNER is seen as the msg.sender | ||
assetVault = new AssetVault(); | ||
|
||
// Transfer some AssetTokens to the AssetVault to ensure sufficient balance for yield distributions | ||
vm.prank(OWNER); | ||
assetToken.transfer(address(assetVault), initialSupply); | ||
} | ||
|
||
/// @dev Test updating yield allowance | ||
function testUpdateYieldAllowance() public { | ||
// The owner of the vault should be able to update the yield allowance | ||
vm.prank(OWNER); // Simulate OWNER being the caller | ||
assetVault.updateYieldAllowance(assetToken, HOLDER_1, 500_000, block.timestamp + 30 days); | ||
|
||
// Check if the allowance was correctly set | ||
uint256 lockedBalance = assetVault.getBalanceLocked(assetToken); | ||
assertEq(lockedBalance, 500_000); | ||
} | ||
|
||
/// @dev Test redistributing yield to asset holders | ||
function testRedistributeYield() public { | ||
// Mint tokens to OWNER | ||
vm.prank(OWNER); | ||
assetToken.mint(OWNER, initialSupply); | ||
|
||
// Distribute some tokens to HOLDER_1 and HOLDER_2 | ||
vm.prank(OWNER); | ||
assetToken.transfer(HOLDER_1, 500); | ||
vm.prank(OWNER); | ||
assetToken.transfer(HOLDER_2, 500); | ||
|
||
// Approve the vault to use the currency token | ||
vm.prank(OWNER); | ||
yieldCurrency.mint(OWNER, 1_000_000); | ||
vm.prank(OWNER); | ||
yieldCurrency.approve(address(assetVault), 1_000_000); | ||
|
||
// Redistribute yield to asset holders | ||
vm.prank(OWNER); | ||
assetVault.redistributeYield(assetToken, yieldCurrency, 1_000_000); | ||
|
||
// Check balances after redistribution | ||
uint256 contractBalance = yieldCurrency.balanceOf(address(assetVault)); | ||
assertEq(contractBalance, 0); | ||
|
||
// Check locked balance | ||
uint256 balanceLocked = assetVault.getBalanceLocked(assetToken); | ||
assertEq(balanceLocked, 1_000_000); | ||
} | ||
|
||
/// @dev Test accepting yield allowance | ||
function testAcceptYieldAllowance() public { | ||
// Ensure the vault has sufficient AssetTokens before proceeding | ||
vm.prank(OWNER); | ||
assetToken.transfer(address(assetVault), 500_000); | ||
|
||
// First, OWNER updates allowance for HOLDER_1 | ||
vm.prank(OWNER); | ||
assetVault.updateYieldAllowance(assetToken, HOLDER_1, 500_000, block.timestamp + 30 days); | ||
|
||
// HOLDER_1 accepts the yield allowance | ||
vm.prank(HOLDER_1); | ||
assetVault.acceptYieldAllowance(assetToken, 500_000, block.timestamp + 30 days); | ||
|
||
// Check locked balance | ||
uint256 lockedBalance = assetVault.getBalanceLocked(assetToken); | ||
assertEq(lockedBalance, 500_000); | ||
} | ||
|
||
/// @dev Test renouncing yield distribution | ||
function testRenounceYieldDistribution() public { | ||
// Ensure the vault has sufficient AssetTokens | ||
vm.prank(OWNER); | ||
assetToken.transfer(address(assetVault), 500_000); | ||
|
||
// OWNER sets a yield allowance for HOLDER_1 | ||
vm.prank(OWNER); | ||
assetVault.updateYieldAllowance(assetToken, HOLDER_1, 500_000, block.timestamp + 30 days); | ||
|
||
// HOLDER_1 renounces part of the yield distribution | ||
vm.prank(HOLDER_1); | ||
uint256 renouncedAmount = assetVault.renounceYieldDistribution(assetToken, 250_000, block.timestamp + 30 days); | ||
|
||
// Ensure the renounced amount is correct | ||
assertEq(renouncedAmount, 250_000); | ||
|
||
// Check remaining locked balance | ||
uint256 lockedBalance = assetVault.getBalanceLocked(assetToken); | ||
assertEq(lockedBalance, 250_000); | ||
} | ||
|
||
/// @dev Test clearing all yield distributions | ||
function testClearYieldDistributions() public { | ||
// Ensure the vault has sufficient AssetTokens | ||
vm.prank(OWNER); | ||
assetToken.transfer(address(assetVault), 500_000); | ||
|
||
// OWNER sets yield allowances for HOLDER_1 and HOLDER_2 | ||
vm.prank(OWNER); | ||
assetVault.updateYieldAllowance(assetToken, HOLDER_1, 500_000, block.timestamp + 30 days); | ||
vm.prank(OWNER); | ||
assetVault.updateYieldAllowance(assetToken, HOLDER_2, 500_000, block.timestamp + 30 days); | ||
|
||
// OWNER clears all yield distributions | ||
vm.prank(OWNER); | ||
assetVault.clearYieldDistributions(assetToken); | ||
|
||
// Check that locked balance is cleared | ||
uint256 lockedBalance = assetVault.getBalanceLocked(assetToken); | ||
assertEq(lockedBalance, 0); | ||
} | ||
|
||
/// @dev Test wallet function in the vault | ||
function testWalletFunction() public { | ||
// Check that wallet returns the correct address (in this case, it should be the contract itself) | ||
address walletAddress = assetVault.wallet(); | ||
assertEq(walletAddress, address(assetVault)); | ||
} | ||
|
||
} |