@@ -4,6 +4,9 @@ pragma solidity 0.8.30;
44import { IZToken, ZNative } from "../../src/ZNative.sol " ;
55import { SetUp } from "./utils/SetUp.sol " ;
66import { FixedPointMathLib } from "solady/utils/FixedPointMathLib.sol " ;
7+ // import { console } from "forge-std/console.sol";
8+
9+ error InsufficientBalance ();
710
811contract ZNativeTest is SetUp {
912 using FixedPointMathLib for uint256 ;
@@ -24,12 +27,12 @@ contract ZNativeTest is SetUp {
2427 assertGt (bytes (native.symbol ()).length , 0 );
2528 }
2629
27- function test_Mint_RevertWhen_zAmountIsZero () external {
30+ function test_Mint_WhenZTokenAmountIsZero () external {
2831 vm.expectRevert (IZToken.ZeroAmountIsNotAllowed.selector );
2932 native.mint (0 );
3033 }
3134
32- function test_Mint_WhenzAmountIsGreaterThanZero (uint256 _zAmount ) external {
35+ function test_Mint_WhenZTokenAmountIsValid (uint256 _zAmount ) external {
3336 _zAmount = bound (_zAmount, 1000 , type (uint64 ).max);
3437
3538 uint256 expectedUnderlyingTokenAmount = native.getExchangeRate ().mulWad (_zAmount);
@@ -60,7 +63,7 @@ contract ZNativeTest is SetUp {
6063 native.deposit ();
6164 }
6265
63- function test_Deposit_WhenZAmountIsGreaterThanZero (uint256 _underlyingAmount ) external {
66+ function test_Deposit_WhenZTokenAmountIsValid (uint256 _underlyingAmount ) external {
6467 uint256 balance = lender.balance;
6568 _underlyingAmount = bound (_underlyingAmount, 1000 , balance);
6669
@@ -76,4 +79,135 @@ contract ZNativeTest is SetUp {
7679 assertEq (native.balanceOf (lender), zAmount);
7780 assertEq (address (native).balance, _underlyingAmount);
7881 }
82+
83+ function test_Redeem_WhenZTokenRedeemAmountIsZero () external {
84+ vm.expectRevert (IZToken.ZeroAmountIsNotAllowed.selector );
85+ native.redeem (0 );
86+ }
87+
88+ modifier whenDepositAmountIsValid (uint256 _underlyingAmount ) {
89+ uint256 balance = lender.balance;
90+ _underlyingAmount = bound (_underlyingAmount, 1e18 , balance);
91+ vm.prank (lender);
92+ native.deposit { value: _underlyingAmount }();
93+ _;
94+ }
95+
96+ modifier whenZTokenRedeemAmountIsValid (uint256 _underlyingAmount ) {
97+ _;
98+ }
99+
100+ function test_Redeem_WhenZTokenRedeemAmountIsValid (uint256 _underlyingAmount )
101+ external
102+ whenDepositAmountIsValid (_underlyingAmount)
103+ {
104+ uint256 balance = lender.balance;
105+
106+ uint256 lenderZTokenBalanceBefore = native.balanceOf (lender);
107+ uint256 expectedUnderlyingAmount = lenderZTokenBalanceBefore.mulWad (native.getExchangeRate ());
108+ uint256 zTokenTotalSupplyBefore = native.totalSupply ();
109+
110+ vm.expectEmit (address (native));
111+ emit IZToken.Redeemed (lender, lenderZTokenBalanceBefore, expectedUnderlyingAmount);
112+
113+ vm.prank (lender);
114+ uint256 underlyingAmount = native.redeem (lenderZTokenBalanceBefore);
115+
116+ uint256 lenderNativeTokenBalanceAfter = lender.balance;
117+ uint256 lenderZTokenBalanceAfter = native.balanceOf (lender);
118+ uint256 zTokenTotalSupplyAfter = native.totalSupply ();
119+
120+ assertEq (lenderZTokenBalanceAfter, 0 );
121+ assertEq (zTokenTotalSupplyAfter, zTokenTotalSupplyBefore - lenderZTokenBalanceBefore);
122+ assertEq (lenderNativeTokenBalanceAfter, balance + underlyingAmount);
123+ }
124+
125+ function test_Withraw_WhenUnderlyingWithdrawalAmountIsZero () external {
126+ vm.expectRevert (IZToken.ZeroAmountIsNotAllowed.selector );
127+ native.withdraw (0 );
128+ }
129+
130+ modifier whenUnderlyingWithdrawalAmountIsValid () {
131+ _;
132+ }
133+
134+ function test_Withraw_WhenUnderlyingWithdrawalAmountIsValid (uint256 _underlyingAmount )
135+ external
136+ whenDepositAmountIsValid (_underlyingAmount)
137+ whenUnderlyingWithdrawalAmountIsValid
138+ {
139+ uint256 balance = lender.balance;
140+ uint256 lenderZTokenBalanceBefore = native.balanceOf (lender);
141+ uint256 zTokenTotalSupplyBefore = native.totalSupply ();
142+
143+ uint256 lenderUnderlyingBalance = lenderZTokenBalanceBefore.mulWad (native.getExchangeRate ());
144+
145+ vm.expectEmit (address (native));
146+ emit IZToken.Withdrawn (lender, lenderUnderlyingBalance, lenderZTokenBalanceBefore);
147+
148+ vm.prank (lender);
149+ uint256 zAmount = native.withdraw (lenderUnderlyingBalance);
150+ assertEq (native.totalSupply (), zTokenTotalSupplyBefore - zAmount);
151+ assertEq (native.balanceOf (lender), lenderZTokenBalanceBefore - zAmount);
152+ assertEq (lender.balance, balance + lenderUnderlyingBalance);
153+
154+ // it should accure interest before processing the withrawal
155+ }
156+
157+ function test_DepositCollateral_WhenUnderlyingCollateralAmountIsZero () external {
158+ // it should revert with ZeroAmountIsNotAllowed
159+ vm.expectRevert (IZToken.ZeroAmountIsNotAllowed.selector );
160+ native.depositCollateral { value: 0 }();
161+ }
162+
163+ function test_DepositCollateral_WhenUnderlyingCollateralAmountIsValid (uint256 _underlyingAmount ) external {
164+ uint256 balance = borrower.balance;
165+ _underlyingAmount = bound (_underlyingAmount, 1e18 , balance);
166+
167+ uint256 contractBalanceBefore = address (native).balance;
168+
169+ // it should emit a CollateralDeposited event
170+ vm.expectEmit (address (native));
171+ emit IZToken.CollateralDeposited (borrower, _underlyingAmount, _underlyingAmount);
172+
173+ vm.prank (borrower);
174+ native.depositCollateral { value: _underlyingAmount }();
175+ // it should transfer the underlying to this contract
176+ assertEq (address (native).balance, contractBalanceBefore + _underlyingAmount);
177+ // it should update the user collateral balance
178+ }
179+
180+ function test_RedeemForCollateral_WhenZTokenCollateralAmountIsZero () external {
181+ // it should revert with ZeroAmountIsNotAllowed
182+ vm.expectRevert (IZToken.ZeroAmountIsNotAllowed.selector );
183+ native.redeemForCollateral (0 );
184+ }
185+
186+ // another when to do this after multiple borrows
187+ // another when to do this after multiple deposit
188+ // another when after certain % of liquidation
189+ function test_RedeemForCollateral_WhenZTokenCollateralAmountIsValid (uint256 _underlyingAmount , uint256 _zAmount )
190+ external
191+ whenDepositAmountIsValid (_underlyingAmount)
192+ {
193+ uint256 lenderZTokenBalanceBefore = native.balanceOf (lender);
194+ _zAmount = bound (_zAmount, 1e18 , lenderZTokenBalanceBefore);
195+ uint256 contractBalanceBefore = address (native).balance;
196+
197+ uint256 expectedCollateralAmount = _zAmount.mulWad (native.getExchangeRate ());
198+
199+ vm.expectEmit (address (native));
200+ emit IZToken.CollateralRedeemed (lender, _zAmount, expectedCollateralAmount, expectedCollateralAmount);
201+
202+ vm.prank (lender);
203+ uint256 collateralAmount = native.redeemForCollateral (_zAmount);
204+
205+ // it should accure interest
206+ // it should burn the ZToken
207+ assertEq (native.balanceOf (lender), lenderZTokenBalanceBefore - _zAmount);
208+ // it should transfer the underlying token to this contract
209+ assertEq (address (native).balance, contractBalanceBefore + collateralAmount);
210+ // it should update the user collateral balance
211+ // it should emit a CollateralRedeemed event
212+ }
79213}
0 commit comments