From 7993e7c8f6e4b2a4d0373b3cf4157325234ccbc6 Mon Sep 17 00:00:00 2001 From: sakulstra Date: Fri, 9 Aug 2024 21:55:06 +0200 Subject: [PATCH] fix: cleanup tests --- .../contracts/static-a-token/StataOracle.sol | 2 +- .../static-a-token/StaticATokenLM.sol | 111 +------- tests/periphery/static-a-token/Pausable.t.sol | 2 +- tests/periphery/static-a-token/Rewards.t.sol | 45 +++- .../static-a-token/StataOracle.t.sol | 32 +++ .../static-a-token/StaticATokenLM.t.sol | 71 ----- .../StaticATokenMetaTransactions.t.sol | 245 ------------------ 7 files changed, 79 insertions(+), 429 deletions(-) delete mode 100644 tests/periphery/static-a-token/StaticATokenMetaTransactions.t.sol diff --git a/src/periphery/contracts/static-a-token/StataOracle.sol b/src/periphery/contracts/static-a-token/StataOracle.sol index c414f918..1a715b07 100644 --- a/src/periphery/contracts/static-a-token/StataOracle.sol +++ b/src/periphery/contracts/static-a-token/StataOracle.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol"; +import {IERC4626} from '@openzeppelin/contracts/interfaces/IERC4626.sol'; import {IPool} from '../../../core/contracts/interfaces/IPool.sol'; import {IPoolAddressesProvider} from '../../../core/contracts/interfaces/IPoolAddressesProvider.sol'; import {IAaveOracle} from '../../../core/contracts/interfaces/IAaveOracle.sol'; diff --git a/src/periphery/contracts/static-a-token/StaticATokenLM.sol b/src/periphery/contracts/static-a-token/StaticATokenLM.sol index b12c029f..aba4c20b 100644 --- a/src/periphery/contracts/static-a-token/StaticATokenLM.sol +++ b/src/periphery/contracts/static-a-token/StaticATokenLM.sol @@ -6,7 +6,7 @@ import {ERC20Upgradeable} from 'openzeppelin-contracts-upgradeable/contracts/tok import {ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol'; import {ERC20PausableUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PausableUpgradeable.sol'; import {ERC4626Upgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol'; -import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol"; +import {IERC4626} from '@openzeppelin/contracts/interfaces/IERC4626.sol'; import {IPool} from '../../../core/contracts/interfaces/IPool.sol'; import {IPoolAddressesProvider} from '../../../core/contracts/interfaces/IPoolAddressesProvider.sol'; @@ -49,15 +49,6 @@ contract StaticATokenLM is using WadRayMath for uint256; using RayMathExplicitRounding for uint256; - bytes32 public constant METADEPOSIT_TYPEHASH = - keccak256( - 'Deposit(address depositor,address receiver,uint256 assets,uint16 referralCode,bool depositToAave,uint256 nonce,uint256 deadline)' - ); - bytes32 public constant METAWITHDRAWAL_TYPEHASH = - keccak256( - 'Withdraw(address owner,address receiver,uint256 shares,uint256 assets,bool withdrawFromAave,uint256 nonce,uint256 deadline)' - ); - uint256 public constant STATIC__ATOKEN_LM_REVISION = 3; IPool public immutable POOL; @@ -148,106 +139,6 @@ contract StaticATokenLM is return shares; } - // ///@inheritdoc IStaticATokenLM - // function metaDeposit( - // address depositor, - // address receiver, - // uint256 assets, - // uint16 referralCode, - // bool depositToAave, - // uint256 deadline, - // PermitParams calldata permit, - // SignatureParams calldata sigParams - // ) external returns (uint256) { - // require(depositor != address(0), StaticATokenErrors.INVALID_DEPOSITOR); - // //solium-disable-next-line - // require(deadline >= block.timestamp, StaticATokenErrors.INVALID_EXPIRATION); - // // Unchecked because the only math done is incrementing - // // the owner's nonce which cannot realistically overflow. - // unchecked { - // bytes32 digest = keccak256( - // abi.encodePacked( - // '\x19\x01', - // _domainSeparatorV4(), - // keccak256( - // abi.encode( - // METADEPOSIT_TYPEHASH, - // depositor, - // receiver, - // assets, - // referralCode, - // depositToAave, - // _useNonce(depositor), - // deadline - // ) - // ) - // ) - // ); - // require( - // depositor == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), - // StaticATokenErrors.INVALID_SIGNATURE - // ); - // } - // // assume if deadline 0 no permit was supplied - // if (permit.deadline != 0) { - // try - // IERC20WithPermit(depositToAave ? address(_aTokenUnderlying) : address(_aToken)).permit( - // depositor, - // address(this), - // permit.value, - // permit.deadline, - // permit.v, - // permit.r, - // permit.s - // ) - // {} catch {} - // } - // (uint256 shares, ) = _deposit(depositor, receiver, 0, assets, referralCode, depositToAave); - // return shares; - // } - - // ///@inheritdoc IStaticATokenLM - // function metaWithdraw( - // address owner, - // address receiver, - // uint256 shares, - // uint256 assets, - // bool withdrawFromAave, - // uint256 deadline, - // SignatureParams calldata sigParams - // ) external returns (uint256, uint256) { - // require(owner != address(0), StaticATokenErrors.INVALID_OWNER); - // //solium-disable-next-line - // require(deadline >= block.timestamp, StaticATokenErrors.INVALID_EXPIRATION); - // // Unchecked because the only math done is incrementing - // // the owner's nonce which cannot realistically overflow. - // unchecked { - // bytes32 digest = keccak256( - // abi.encodePacked( - // '\x19\x01', - // _domainSeparatorV4(), - // keccak256( - // abi.encode( - // METAWITHDRAWAL_TYPEHASH, - // owner, - // receiver, - // shares, - // assets, - // withdrawFromAave, - // _useNonce(owner), - // deadline - // ) - // ) - // ) - // ); - // require( - // owner == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s), - // StaticATokenErrors.INVALID_SIGNATURE - // ); - // } - // return _withdraw(owner, receiver, shares, assets, withdrawFromAave); - // } - ///@inheritdoc IStaticATokenLM function rate() public view returns (uint256) { return POOL.getReserveNormalizedIncome(_aTokenUnderlying); diff --git a/tests/periphery/static-a-token/Pausable.t.sol b/tests/periphery/static-a-token/Pausable.t.sol index 966a33ac..59a24dec 100644 --- a/tests/periphery/static-a-token/Pausable.t.sol +++ b/tests/periphery/static-a-token/Pausable.t.sol @@ -15,7 +15,7 @@ import {IStaticATokenLM} from '../../../src/periphery/contracts/static-a-token/i import {SigUtils} from '../../utils/SigUtils.sol'; import {BaseTest, TestnetERC20} from './TestBase.sol'; -contract Pausable is BaseTest { +contract StataPausableTest is BaseTest { using RayMathExplicitRounding for uint256; function test_setPaused_shouldRevertForInvalidCaller(address actor) external { diff --git a/tests/periphery/static-a-token/Rewards.t.sol b/tests/periphery/static-a-token/Rewards.t.sol index e21c00b2..36a13dd8 100644 --- a/tests/periphery/static-a-token/Rewards.t.sol +++ b/tests/periphery/static-a-token/Rewards.t.sol @@ -5,7 +5,7 @@ import {AToken} from '../../../src/core/contracts/protocol/tokenization/AToken.s import {IERC20} from '../../../src/periphery/contracts/static-a-token/StaticATokenLM.sol'; import {BaseTest} from './TestBase.sol'; -contract StataTokenRewardsTest is BaseTest { +contract StataRewardsTest is BaseTest { function setUp() public override { super.setUp(); @@ -153,4 +153,47 @@ contract StataTokenRewardsTest is BaseTest { assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); assertGe(AToken(UNDERLYING).balanceOf(user), 5 ether); } + + function test_transfer() public { + uint128 amountToDeposit = 10 ether; + _fundUser(amountToDeposit, user); + + _depositAToken(amountToDeposit, user); + + // transfer to 2nd user + staticATokenLM.transfer(user1, amountToDeposit / 2); + assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); + + // forward time + _skipBlocks(60); + + // redeem for both + uint256 claimableUser = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimableUser); + vm.stopPrank(); + vm.startPrank(user1); + uint256 claimableUser1 = staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN); + staticATokenLM.redeem(staticATokenLM.maxRedeem(user1), user1, user1); + staticATokenLM.claimRewardsToSelf(rewardTokens); + assertEq(IERC20(REWARD_TOKEN).balanceOf(user1), claimableUser1); + assertGt(claimableUser1, 0); + + assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); + assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); + assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); + } + + // getUnclaimedRewards + function test_getUnclaimedRewards() public { + uint128 amountToDeposit = 5 ether; + _fundUser(amountToDeposit, user); + + uint256 shares = _depositAToken(amountToDeposit, user); + assertEq(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); + _skipBlocks(1000); + staticATokenLM.redeem(shares, user, user); + assertGt(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); + } } diff --git a/tests/periphery/static-a-token/StataOracle.t.sol b/tests/periphery/static-a-token/StataOracle.t.sol index 3d6b6622..dcbeeac4 100644 --- a/tests/periphery/static-a-token/StataOracle.t.sol +++ b/tests/periphery/static-a-token/StataOracle.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.10; import {StataOracle} from '../../../src/periphery/contracts/static-a-token/StataOracle.sol'; import {StaticATokenLM} from '../../../src/periphery/contracts/static-a-token/StaticATokenLM.sol'; import {BaseTest} from './TestBase.sol'; +import {IPool} from '../../../src/core/contracts/interfaces/IPool.sol'; contract StataOracleTest is BaseTest { StataOracle public oracle; @@ -16,6 +17,7 @@ contract StataOracleTest is BaseTest { contracts.poolConfiguratorProxy.setSupplyCap(UNDERLYING, 1_000_000); } + // ### tests for the dedicated oracle aggregator function test_assetPrice() public view { uint256 stataPrice = oracle.getAssetPrice(address(staticATokenLM)); uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); @@ -54,4 +56,34 @@ contract StataOracleTest is BaseTest { (assets / 1e18) + 1 // there can be imprecision of 1 wei, which will accumulate for each asset ); } + + // ### tests for the token internal oracle + function test_latestAnswer_priceShouldBeEqualOnDefaultIndex() public { + vm.mockCall( + address(POOL), + abi.encodeWithSelector(IPool.getReserveNormalizedIncome.selector), + abi.encode(1e27) + ); + uint256 stataPrice = uint256(staticATokenLM.latestAnswer()); + uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); + assertEq(stataPrice, underlyingPrice); + } + + function test_latestAnswer_priceShouldReflectIndexAccrual(uint256 liquidityIndex) public { + liquidityIndex = bound(liquidityIndex, 1e27, 1e29); + vm.mockCall( + address(POOL), + abi.encodeWithSelector(IPool.getReserveNormalizedIncome.selector), + abi.encode(liquidityIndex) + ); + uint256 stataPrice = uint256(staticATokenLM.latestAnswer()); + uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); + uint256 expectedStataPrice = (underlyingPrice * liquidityIndex) / 1e27; + assertEq(stataPrice, expectedStataPrice); + + // reverse the math to ensure precision loss is within bounds + uint256 reversedUnderlying = (stataPrice * 1e27) / liquidityIndex; + assertApproxEqAbs(underlyingPrice, reversedUnderlying, 1); + } + } diff --git a/tests/periphery/static-a-token/StaticATokenLM.t.sol b/tests/periphery/static-a-token/StaticATokenLM.t.sol index 69df61f1..57009857 100644 --- a/tests/periphery/static-a-token/StaticATokenLM.t.sol +++ b/tests/periphery/static-a-token/StaticATokenLM.t.sol @@ -50,34 +50,6 @@ contract StaticATokenLMTest is BaseTest { ); } - function test_latestAnswer_priceShouldBeEqualOnDefaultIndex() public { - vm.mockCall( - address(POOL), - abi.encodeWithSelector(IPool.getReserveNormalizedIncome.selector), - abi.encode(1e27) - ); - uint256 stataPrice = uint256(staticATokenLM.latestAnswer()); - uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); - assertEq(stataPrice, underlyingPrice); - } - - function test_latestAnswer_priceShouldReflectIndexAccrual(uint256 liquidityIndex) public { - liquidityIndex = bound(liquidityIndex, 1e27, 1e29); - vm.mockCall( - address(POOL), - abi.encodeWithSelector(IPool.getReserveNormalizedIncome.selector), - abi.encode(liquidityIndex) - ); - uint256 stataPrice = uint256(staticATokenLM.latestAnswer()); - uint256 underlyingPrice = contracts.aaveOracle.getAssetPrice(UNDERLYING); - uint256 expectedStataPrice = (underlyingPrice * liquidityIndex) / 1e27; - assertEq(stataPrice, expectedStataPrice); - - // reverse the math to ensure precision loss is within bounds - uint256 reversedUnderlying = (stataPrice * 1e27) / liquidityIndex; - assertApproxEqAbs(underlyingPrice, reversedUnderlying, 1); - } - function test_convertersAndPreviews() public view { uint128 amount = 5 ether; uint256 shares = staticATokenLM.convertToShares(amount); @@ -209,49 +181,6 @@ contract StaticATokenLMTest is BaseTest { staticATokenLM.mint(amountToDeposit, user); } - function test_transfer() public { - uint128 amountToDeposit = 10 ether; - _fundUser(amountToDeposit, user); - - _depositAToken(amountToDeposit, user); - - // transfer to 2nd user - staticATokenLM.transfer(user1, amountToDeposit / 2); - assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); - - // forward time - _skipBlocks(60); - - // redeem for both - uint256 claimableUser = staticATokenLM.getClaimableRewards(user, REWARD_TOKEN); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user), user, user); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user), claimableUser); - vm.stopPrank(); - vm.startPrank(user1); - uint256 claimableUser1 = staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN); - staticATokenLM.redeem(staticATokenLM.maxRedeem(user1), user1, user1); - staticATokenLM.claimRewardsToSelf(rewardTokens); - assertEq(IERC20(REWARD_TOKEN).balanceOf(user1), claimableUser1); - assertGt(claimableUser1, 0); - - assertEq(staticATokenLM.getTotalClaimableRewards(REWARD_TOKEN), 0); - assertEq(staticATokenLM.getClaimableRewards(user, REWARD_TOKEN), 0); - assertEq(staticATokenLM.getClaimableRewards(user1, REWARD_TOKEN), 0); - } - - // getUnclaimedRewards - function test_getUnclaimedRewards() public { - uint128 amountToDeposit = 5 ether; - _fundUser(amountToDeposit, user); - - uint256 shares = _depositAToken(amountToDeposit, user); - assertEq(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); - _skipBlocks(1000); - staticATokenLM.redeem(shares, user, user); - assertGt(staticATokenLM.getUnclaimedRewards(user, REWARD_TOKEN), 0); - } - /** * maxDeposit test */ diff --git a/tests/periphery/static-a-token/StaticATokenMetaTransactions.t.sol b/tests/periphery/static-a-token/StaticATokenMetaTransactions.t.sol deleted file mode 100644 index b5afe5b9..00000000 --- a/tests/periphery/static-a-token/StaticATokenMetaTransactions.t.sol +++ /dev/null @@ -1,245 +0,0 @@ -// // SPDX-License-Identifier: BUSL-1.1 -// pragma solidity ^0.8.10; - -// import {IERC20WithPermit} from 'solidity-utils/contracts/oz-common/interfaces/IERC20WithPermit.sol'; -// import {StaticATokenLM, IStaticATokenLM, IERC20} from '../../../src/periphery/contracts/static-a-token/StaticATokenLM.sol'; -// import {SigUtils} from '../../utils/SigUtils.sol'; -// import {BaseTest, IAToken, IRewardsController, DataTypes} from './TestBase.sol'; - -// contract StaticATokenMetaTransactions is BaseTest { -// function setUp() public override { -// super.setUp(); - -// // Testing meta transactions with USDX as WETH does not support permit -// DataTypes.ReserveDataLegacy memory reserveDataUSDX = contracts.poolProxy.getReserveData( -// address(usdx) -// ); -// UNDERLYING = address(usdx); -// A_TOKEN = reserveDataUSDX.aTokenAddress; - -// staticATokenLM = StaticATokenLM(factory.getStaticAToken(UNDERLYING)); - -// vm.startPrank(user); -// } - -// function test_validateDomainSeparator() public view { -// address[] memory staticATokens = factory.getStaticATokens(); - -// for (uint256 i = 0; i < staticATokens.length; i++) { -// bytes32 separator1 = StaticATokenLM(staticATokens[i]).DOMAIN_SEPARATOR(); -// for (uint256 j = 0; j < staticATokens.length; j++) { -// if (i != j) { -// bytes32 separator2 = StaticATokenLM(staticATokens[j]).DOMAIN_SEPARATOR(); -// assertNotEq(separator1, separator2, 'DOMAIN_SEPARATOR_MUST_BE_UNIQUE'); -// } -// } -// } -// } - -// function test_metaDepositATokenUnderlyingNoPermit() public { -// uint128 amountToDeposit = 5e6; -// deal(UNDERLYING, user, amountToDeposit); -// IERC20(UNDERLYING).approve(address(staticATokenLM), 1e6); -// IStaticATokenLM.PermitParams memory permitParams; - -// // generate combined permit -// SigUtils.MetaDepositParams memory metaDepositParams = SigUtils.MetaDepositParams({ -// depositor: user, -// receiver: spender, -// assets: 1e6, -// referralCode: 0, -// fromUnderlying: true, -// nonce: staticATokenLM.nonces(user), -// deadline: block.timestamp + 1 days -// }); -// bytes32 digest = SigUtils.getTypedDepositHash( -// metaDepositParams, -// staticATokenLM.METADEPOSIT_TYPEHASH(), -// staticATokenLM.DOMAIN_SEPARATOR() -// ); -// (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); - -// IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - -// uint256 previewDeposit = staticATokenLM.previewDeposit(metaDepositParams.assets); -// staticATokenLM.metaDeposit( -// metaDepositParams.depositor, -// metaDepositParams.receiver, -// metaDepositParams.assets, -// metaDepositParams.referralCode, -// metaDepositParams.fromUnderlying, -// metaDepositParams.deadline, -// permitParams, -// sigParams -// ); - -// assertEq(staticATokenLM.balanceOf(metaDepositParams.receiver), previewDeposit); -// } - -// function test_metaDepositATokenUnderlying() public { -// uint128 amountToDeposit = 5e6; -// deal(UNDERLYING, user, amountToDeposit); - -// // permit for aToken deposit -// SigUtils.Permit memory permit = SigUtils.Permit({ -// owner: user, -// spender: address(staticATokenLM), -// value: 1e6, -// nonce: IERC20WithPermit(UNDERLYING).nonces(user), -// deadline: block.timestamp + 1 days -// }); - -// bytes32 permitDigest = SigUtils.getTypedDataHash( -// permit, -// PERMIT_TYPEHASH, -// IERC20WithPermit(UNDERLYING).DOMAIN_SEPARATOR() -// ); - -// (uint8 pV, bytes32 pR, bytes32 pS) = vm.sign(userPrivateKey, permitDigest); - -// IStaticATokenLM.PermitParams memory permitParams = IStaticATokenLM.PermitParams( -// permit.value, -// permit.deadline, -// pV, -// pR, -// pS -// ); - -// // generate combined permit -// SigUtils.MetaDepositParams memory metaDepositParams = SigUtils.MetaDepositParams({ -// depositor: user, -// receiver: spender, -// assets: permit.value, -// referralCode: 0, -// fromUnderlying: true, -// nonce: staticATokenLM.nonces(user), -// deadline: permit.deadline -// }); -// (uint8 v, bytes32 r, bytes32 s) = vm.sign( -// userPrivateKey, -// SigUtils.getTypedDepositHash( -// metaDepositParams, -// staticATokenLM.METADEPOSIT_TYPEHASH(), -// staticATokenLM.DOMAIN_SEPARATOR() -// ) -// ); - -// IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - -// uint256 previewDeposit = staticATokenLM.previewDeposit(metaDepositParams.assets); -// uint256 shares = staticATokenLM.metaDeposit( -// metaDepositParams.depositor, -// metaDepositParams.receiver, -// metaDepositParams.assets, -// metaDepositParams.referralCode, -// metaDepositParams.fromUnderlying, -// metaDepositParams.deadline, -// permitParams, -// sigParams -// ); -// assertEq(shares, previewDeposit); -// assertEq(staticATokenLM.balanceOf(metaDepositParams.receiver), previewDeposit); -// } - -// function test_metaDepositAToken() public { -// uint128 amountToDeposit = 5e6; -// _fundUser(amountToDeposit, user); -// _underlyingToAToken(amountToDeposit, user); - -// // permit for aToken deposit -// SigUtils.Permit memory permit = SigUtils.Permit({ -// owner: user, -// spender: address(staticATokenLM), -// value: 1e6, -// nonce: IERC20WithPermit(A_TOKEN).nonces(user), -// deadline: block.timestamp + 1 days -// }); - -// bytes32 permitDigest = SigUtils.getTypedDataHash( -// permit, -// PERMIT_TYPEHASH, -// IERC20WithPermit(A_TOKEN).DOMAIN_SEPARATOR() -// ); - -// (uint8 pV, bytes32 pR, bytes32 pS) = vm.sign(userPrivateKey, permitDigest); - -// IStaticATokenLM.PermitParams memory permitParams = IStaticATokenLM.PermitParams( -// permit.value, -// permit.deadline, -// pV, -// pR, -// pS -// ); - -// // generate combined permit -// SigUtils.MetaDepositParams memory metaDepositParams = SigUtils.MetaDepositParams({ -// depositor: user, -// receiver: spender, -// assets: permit.value, -// referralCode: 0, -// fromUnderlying: false, -// nonce: staticATokenLM.nonces(user), -// deadline: permit.deadline -// }); -// bytes32 digest = SigUtils.getTypedDepositHash( -// metaDepositParams, -// staticATokenLM.METADEPOSIT_TYPEHASH(), -// staticATokenLM.DOMAIN_SEPARATOR() -// ); -// (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); - -// IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - -// uint256 previewDeposit = staticATokenLM.previewDeposit(metaDepositParams.assets); - -// staticATokenLM.metaDeposit( -// metaDepositParams.depositor, -// metaDepositParams.receiver, -// metaDepositParams.assets, -// metaDepositParams.referralCode, -// metaDepositParams.fromUnderlying, -// metaDepositParams.deadline, -// permitParams, -// sigParams -// ); - -// assertEq(staticATokenLM.balanceOf(metaDepositParams.receiver), previewDeposit); -// } - -// function test_metaWithdraw() public { -// uint128 amountToDeposit = 5e6; -// _fundUser(amountToDeposit, user); - -// _depositAToken(amountToDeposit, user); - -// SigUtils.MetaWithdrawParams memory permit = SigUtils.MetaWithdrawParams({ -// owner: user, -// spender: spender, -// staticAmount: 0, -// dynamicAmount: 1e6, -// toUnderlying: false, -// nonce: staticATokenLM.nonces(user), -// deadline: block.timestamp + 1 days -// }); -// bytes32 digest = SigUtils.getTypedWithdrawHash( -// permit, -// staticATokenLM.METAWITHDRAWAL_TYPEHASH(), -// staticATokenLM.DOMAIN_SEPARATOR() -// ); -// (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, digest); - -// IStaticATokenLM.SignatureParams memory sigParams = IStaticATokenLM.SignatureParams(v, r, s); - -// staticATokenLM.metaWithdraw( -// permit.owner, -// permit.spender, -// permit.staticAmount, -// permit.dynamicAmount, -// permit.toUnderlying, -// permit.deadline, -// sigParams -// ); - -// assertEq(IERC20(A_TOKEN).balanceOf(permit.spender), permit.dynamicAmount); -// } -// }