From bd5b9a9d38be078f9c4439d3d4359818dbec7384 Mon Sep 17 00:00:00 2001 From: sakulstra Date: Thu, 15 Aug 2024 23:59:43 +0200 Subject: [PATCH] feat: improve tests --- .../static-a-token/StaticATokenFactory.sol | 7 +- .../ERC20AaveLMUpgradable.t.sol | 22 +++ .../ERC4626StataTokenUpgradeable.t.sol | 106 +++++++++++++-- .../static-a-token/Stata4626LM.t.sol | 128 ------------------ .../static-a-token/StataTokenV2Getters.sol | 35 +++++ .../static-a-token/StataTokenV2Pausable.t.sol | 9 ++ .../static-a-token/StataTokenV2Permit.sol | 88 +++++++++--- .../static-a-token/StataTokenV2Rescuable.sol | 88 +++--------- .../static-a-token/StaticATokenNoLM.t.sol | 51 ------- 9 files changed, 259 insertions(+), 275 deletions(-) delete mode 100644 tests/periphery/static-a-token/Stata4626LM.t.sol create mode 100644 tests/periphery/static-a-token/StataTokenV2Getters.sol delete mode 100644 tests/periphery/static-a-token/StaticATokenNoLM.t.sol diff --git a/src/periphery/contracts/static-a-token/StaticATokenFactory.sol b/src/periphery/contracts/static-a-token/StaticATokenFactory.sol index d5259eeb..91af7f72 100644 --- a/src/periphery/contracts/static-a-token/StaticATokenFactory.sol +++ b/src/periphery/contracts/static-a-token/StaticATokenFactory.sol @@ -51,7 +51,8 @@ contract StaticATokenFactory is Initializable, IStaticATokenFactory { revert NotListedUnderlying(reserveData.aTokenAddress); bytes memory symbol = abi.encodePacked( 'stat', - IERC20Metadata(reserveData.aTokenAddress).symbol() + IERC20Metadata(reserveData.aTokenAddress).symbol(), + 'v2' ); address staticAToken = TRANSPARENT_PROXY_FACTORY.createDeterministic( STATIC_A_TOKEN_IMPL, @@ -59,7 +60,9 @@ contract StaticATokenFactory is Initializable, IStaticATokenFactory { abi.encodeWithSelector( StataTokenV2.initialize.selector, reserveData.aTokenAddress, - string(abi.encodePacked('Static ', IERC20Metadata(reserveData.aTokenAddress).name())), + string( + abi.encodePacked('Static ', IERC20Metadata(reserveData.aTokenAddress).name(), ' v2') + ), string(symbol) ), bytes32(uint256(uint160(underlyings[i]))) diff --git a/tests/periphery/static-a-token/ERC20AaveLMUpgradable.t.sol b/tests/periphery/static-a-token/ERC20AaveLMUpgradable.t.sol index 22eea153..fea11546 100644 --- a/tests/periphery/static-a-token/ERC20AaveLMUpgradable.t.sol +++ b/tests/periphery/static-a-token/ERC20AaveLMUpgradable.t.sol @@ -85,6 +85,28 @@ contract ERC20AaveLMUpgradableTest is TestnetProcedures { contracts.emissionManager.setEmissionAdmin(rewardToken, emissionAdmin); } + function test_2701() external view { + assertEq( + keccak256(abi.encode(uint256(keccak256('aave-dao.storage.ERC20AaveLM')) - 1)) & + ~bytes32(uint256(0xff)), + 0x4fad66563f105be0bff96185c9058c4934b504d3ba15ca31e86294f0b01fd200 + ); + } + + function test_noRewardsInitialized() external { + vm.expectRevert( + abi.encodeWithSelector(IERC20AaveLM.RewardNotInitialized.selector, rewardToken) + ); + lmUpgradeable.getClaimableRewards(user, rewardToken); + } + + function test_noopWhenNotInitialized() external { + assertEq(IERC20(rewardToken).balanceOf(address(lmUpgradeable)), 0); + assertEq(lmUpgradeable.getTotalClaimableRewards(rewardToken), 0); + assertEq(lmUpgradeable.collectAndUpdateRewards(rewardToken), 0); + assertEq(IERC20(rewardToken).balanceOf(address(lmUpgradeable)), 0); + } + function test_claimableRewards( uint256 depositAmount, uint32 emissionEnd, diff --git a/tests/periphery/static-a-token/ERC4626StataTokenUpgradeable.t.sol b/tests/periphery/static-a-token/ERC4626StataTokenUpgradeable.t.sol index d9e0ce7c..0a859df0 100644 --- a/tests/periphery/static-a-token/ERC4626StataTokenUpgradeable.t.sol +++ b/tests/periphery/static-a-token/ERC4626StataTokenUpgradeable.t.sol @@ -5,7 +5,7 @@ import {IERC20Errors} from 'openzeppelin-contracts/contracts/interfaces/draft-IE import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol'; import {IPool} from '../../../src/core/contracts/interfaces/IPool.sol'; import {TestnetProcedures, TestnetERC20} from '../../utils/TestnetProcedures.sol'; -import {ERC4626StataTokenUpgradeable, IERC4626StataToken} from '../../../src/periphery/contracts/static-a-token/ERC4626StataTokenUpgradeable.sol'; +import {ERC4626Upgradeable, ERC4626StataTokenUpgradeable, IERC4626StataToken} from '../../../src/periphery/contracts/static-a-token/ERC4626StataTokenUpgradeable.sol'; import {IRewardsController} from '../../../src/periphery/contracts/rewards/interfaces/IRewardsController.sol'; import {PullRewardsTransferStrategy, ITransferStrategyBase} from '../../../src/periphery/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol'; import {RewardsDataTypes} from '../../../src/periphery/contracts/rewards/libraries/RewardsDataTypes.sol'; @@ -44,6 +44,24 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures { erc4626Upgradeable.mockInit(address(reserveDataWETH.aTokenAddress)); } + function test_2701() external view { + assertEq( + keccak256(abi.encode(uint256(keccak256('aave-dao.storage.ERC4626StataToken')) - 1)) & + ~bytes32(uint256(0xff)), + 0x55029d3f54709e547ed74b2fc842d93107ab1490ab7555dd9dd0bf6451101900 + ); + } + + // ### GETTERS TESTS ### + function test_convertersAndPreviews(uint128 assets) public view { + uint256 shares = erc4626Upgradeable.convertToShares(assets); + assertEq(shares, erc4626Upgradeable.previewDeposit(assets)); + assertEq(shares, erc4626Upgradeable.previewWithdraw(assets)); + assertEq(erc4626Upgradeable.convertToAssets(shares), assets); + assertEq(erc4626Upgradeable.previewMint(shares), assets); + assertEq(erc4626Upgradeable.previewRedeem(shares), assets); + } + // ### DEPOSIT TESTS ### function test_depositATokens(uint128 assets, address receiver) public { vm.assume(receiver != address(0)); @@ -70,7 +88,7 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures { vm.expectRevert(); // underflows vm.prank(user); - uint256 shares = erc4626Upgradeable.depositATokens(env.amount, user); + erc4626Upgradeable.depositATokens(env.amount, user); } // ### REDEEM TESTS ### @@ -80,10 +98,10 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures { uint256 shares = _fund4626(env.amount, user); vm.prank(user); - erc4626Upgradeable.redeemATokens(shares, receiver, user); + uint256 redeemedAssets = erc4626Upgradeable.redeemATokens(shares, receiver, user); assertEq(erc4626Upgradeable.balanceOf(user), 0); - assertEq(IERC20(aToken).balanceOf(receiver), env.amount); + assertEq(IERC20(aToken).balanceOf(receiver), redeemedAssets); } function test_redeemATokens_onBehalf_shouldRevert_insufficientAllowance( @@ -113,8 +131,80 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures { uint256 shares = _fund4626(env.amount, user); vm.prank(user); - erc4626Upgradeable.approve(address(this), env.amount); - erc4626Upgradeable.redeemATokens(env.amount, address(this), user); + erc4626Upgradeable.approve(address(this), shares); + uint256 redeemedAssets = erc4626Upgradeable.redeemATokens(shares, address(this), user); + + assertEq(erc4626Upgradeable.balanceOf(user), 0); + assertEq(IERC20(aToken).balanceOf(address(this)), redeemedAssets); + } + + function test_redeem(uint256 assets, address receiver) external { + vm.assume(receiver != address(0)); + TestEnv memory env = _setupTestEnv(assets); + uint256 shares = _fund4626(env.amount, user); + + vm.prank(user); + uint256 redeemedAssets = erc4626Upgradeable.redeem(shares, receiver, user); + assertEq(erc4626Upgradeable.balanceOf(user), 0); + assertLe(IERC20(underlying).balanceOf(receiver), redeemedAssets); + } + + // ### withdraw TESTS ### + function test_withdraw(uint256 assets, address receiver) public { + vm.assume(receiver != address(0)); + TestEnv memory env = _setupTestEnv(assets); + uint256 shares = _fund4626(env.amount, user); + + vm.prank(user); + uint256 withdrawnShares = erc4626Upgradeable.withdraw(env.amount, receiver, user); + assertEq(withdrawnShares, shares); + assertEq(erc4626Upgradeable.balanceOf(user), 0); + assertLe(IERC20(underlying).balanceOf(receiver), env.amount); + assertApproxEqAbs(IERC20(underlying).balanceOf(receiver), env.amount, 1); + } + + function test_withdraw_shouldRevert_moreThenAvailable(uint256 assets, address receiver) public { + vm.assume(receiver != address(0)); + TestEnv memory env = _setupTestEnv(assets); + _fund4626(env.amount, user); + + vm.prank(user); + vm.expectRevert( + abi.encodeWithSelector( + ERC4626Upgradeable.ERC4626ExceededMaxWithdraw.selector, + address(user), + env.amount + 1, + env.amount + ) + ); + erc4626Upgradeable.withdraw(env.amount + 1, receiver, user); + } + + // ### mint TESTS ### + function test_mint(uint256 assets, address receiver) public { + vm.assume(receiver != address(0)); + TestEnv memory env = _setupTestEnv(assets); + _fundUnderlying(env.amount, user); + + vm.startPrank(user); + IERC20(underlying).approve(address(erc4626Upgradeable), env.amount); + uint256 shares = erc4626Upgradeable.previewDeposit(env.amount); + uint256 assetsUsedForMinting = erc4626Upgradeable.mint(shares, receiver); + assertEq(assetsUsedForMinting, env.amount); + assertEq(erc4626Upgradeable.balanceOf(receiver), shares); + } + + function test_mint_shouldRevert_mintMoreThenBalance(uint256 assets, address receiver) public { + vm.assume(receiver != address(0)); + TestEnv memory env = _setupTestEnv(assets); + _fundUnderlying(env.amount, user); + + vm.startPrank(user); + IERC20(underlying).approve(address(erc4626Upgradeable), type(uint256).max); + uint256 shares = erc4626Upgradeable.previewDeposit(env.amount); + + vm.expectRevert(); + uint256 assetsUsedForMinting = erc4626Upgradeable.mint(shares + 1, receiver); } // ### maxDeposit TESTS ### @@ -161,7 +251,7 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures { // ### maxRedeem TESTS ### function test_maxRedeem_paused(uint128 assets) public { TestEnv memory env = _setupTestEnv(assets); - uint256 shares = _fund4626(env.amount, user); + _fund4626(env.amount, user); vm.prank(address(roleList.marketOwner)); contracts.poolConfiguratorProxy.setReservePause(underlying, true); @@ -233,7 +323,7 @@ contract ERC4626StataTokenUpgradeableTest is TestnetProcedures { function _setupTestEnv(uint256 amount) internal returns (TestEnv memory) { TestEnv memory env; - env.amount = bound(amount, 1, type(uint128).max); + env.amount = bound(amount, 1, type(uint96).max); return env; } diff --git a/tests/periphery/static-a-token/Stata4626LM.t.sol b/tests/periphery/static-a-token/Stata4626LM.t.sol deleted file mode 100644 index 987657ba..00000000 --- a/tests/periphery/static-a-token/Stata4626LM.t.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.10; - -import {IRescuable} from 'solidity-utils/contracts/utils/Rescuable.sol'; -import {ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol'; -import {Initializable} from 'openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol'; -import {IERC20Metadata, IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol'; - -import {AToken} from '../../../src/core/contracts/protocol/tokenization/AToken.sol'; -import {DataTypes} from '../../../src/core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {Math} from '../../../src/periphery/contracts/static-a-token/ERC4626StataTokenUpgradeable.sol'; -import {StataTokenV2} from '../../../src/periphery/contracts/static-a-token/StataTokenV2.sol'; // TODO: change import to isolate to 4626 -import {SigUtils} from '../../utils/SigUtils.sol'; -import {BaseTest, TestnetERC20} from './TestBase.sol'; -import {IPool} from '../../../src/core/contracts/interfaces/IPool.sol'; - -contract Stata4626LMTest is BaseTest { - function test_initializeShouldRevert() public { - address impl = factory.STATIC_A_TOKEN_IMPL(); - vm.expectRevert(Initializable.InvalidInitialization.selector); - StataTokenV2(impl).initialize(aToken, 'hey', 'ho'); - } - - function test_getters() public view { - assertEq(stataTokenV2.name(), 'Static Aave Local WETH'); - assertEq(stataTokenV2.symbol(), 'stataLocWETH'); - - address referenceAsset = stataTokenV2.getReferenceAsset(); - assertEq(referenceAsset, aToken); - - address underlyingAddress = address(stataTokenV2.asset()); - assertEq(underlyingAddress, underlying); - - IERC20Metadata underlying = IERC20Metadata(underlyingAddress); - assertEq(stataTokenV2.decimals(), underlying.decimals()); - - assertEq( - address(stataTokenV2.INCENTIVES_CONTROLLER()), - address(AToken(aToken).getIncentivesController()) - ); - } - - function test_convertersAndPreviews() public view { - uint128 amount = 5 ether; - uint256 shares = stataTokenV2.convertToShares(amount); - assertLe(shares, amount, 'SHARES LOWER'); - assertEq(shares, stataTokenV2.previewDeposit(amount), 'PREVIEW_DEPOSIT'); - assertLe(shares, stataTokenV2.previewWithdraw(amount), 'PREVIEW_WITHDRAW'); - uint256 assets = stataTokenV2.convertToAssets(amount); - assertGe(assets, shares, 'ASSETS GREATER'); - assertLe(assets, stataTokenV2.previewMint(amount), 'PREVIEW_MINT'); - assertEq(assets, stataTokenV2.previewRedeem(amount), 'PREVIEW_REDEEM'); - } - - // Redeem tests - function test_redeem() public { - uint128 amountToDeposit = 5 ether; - - _fund4626(amountToDeposit, user); - - assertEq(stataTokenV2.maxRedeem(user), stataTokenV2.balanceOf(user)); - stataTokenV2.redeem(stataTokenV2.maxRedeem(user), user, user); - assertEq(stataTokenV2.balanceOf(user), 0); - assertLe(IERC20(underlying).balanceOf(user), amountToDeposit); - assertApproxEqAbs(IERC20(underlying).balanceOf(user), amountToDeposit, 1); - } - - function test_redeemAToken() public { - uint128 amountToDeposit = 5 ether; - _fund4626(amountToDeposit, user); - - assertEq(stataTokenV2.maxRedeem(user), stataTokenV2.balanceOf(user)); - stataTokenV2.redeemATokens(stataTokenV2.maxRedeem(user), user, user); - assertEq(stataTokenV2.balanceOf(user), 0); - assertLe(IERC20(aToken).balanceOf(user), amountToDeposit); - assertApproxEqAbs(IERC20(aToken).balanceOf(user), amountToDeposit, 1); - } - - // Withdraw tests - function test_withdraw() public { - uint128 amountToDeposit = 5 ether; - _fund4626(amountToDeposit, user); - - assertLe(stataTokenV2.maxWithdraw(user), amountToDeposit); - stataTokenV2.withdraw(stataTokenV2.maxWithdraw(user), user, user); - assertEq(stataTokenV2.balanceOf(user), 0); - assertLe(IERC20(underlying).balanceOf(user), amountToDeposit); - assertApproxEqAbs(IERC20(underlying).balanceOf(user), amountToDeposit, 1); - } - - function testFail_withdrawAboveBalance() public { - uint128 amountToDeposit = 5 ether; - - _fundAToken(amountToDeposit, user); - _fundAToken(amountToDeposit, user1); - - assertEq(stataTokenV2.maxWithdraw(user), amountToDeposit); - stataTokenV2.withdraw(stataTokenV2.maxWithdraw(user) + 1, user, user); - } - - // mint - function test_mint() public { - vm.stopPrank(); - - // set supply cap to non-zero - vm.startPrank(poolAdmin); - contracts.poolConfiguratorProxy.setSupplyCap(underlying, 15_000); - vm.stopPrank(); - - vm.startPrank(user); - - uint128 amountToDeposit = 5 ether; - _fundUnderlying(amountToDeposit, user); - - IERC20(underlying).approve(address(stataTokenV2), amountToDeposit); - uint256 shares = 1 ether; - stataTokenV2.mint(shares, user); - assertEq(shares, stataTokenV2.balanceOf(user)); - } - - function testFail_mintAboveBalance() public { - uint128 amountToDeposit = 5 ether; - _fund4626(amountToDeposit, user); - - IERC20(aToken).approve(address(stataTokenV2), amountToDeposit); - stataTokenV2.mint(amountToDeposit, user); - } -} diff --git a/tests/periphery/static-a-token/StataTokenV2Getters.sol b/tests/periphery/static-a-token/StataTokenV2Getters.sol new file mode 100644 index 00000000..425ada34 --- /dev/null +++ b/tests/periphery/static-a-token/StataTokenV2Getters.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +import {Initializable} from 'openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol'; +import {IERC20Metadata, IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol'; +import {AToken} from '../../../src/core/contracts/protocol/tokenization/AToken.sol'; +import {StataTokenV2} from '../../../src/periphery/contracts/static-a-token/StataTokenV2.sol'; // TODO: change import to isolate to 4626 +import {BaseTest} from './TestBase.sol'; + +contract StataTokenV2GettersTest is BaseTest { + function test_initializeShouldRevert() public { + address impl = factory.STATIC_A_TOKEN_IMPL(); + vm.expectRevert(Initializable.InvalidInitialization.selector); + StataTokenV2(impl).initialize(aToken, 'hey', 'ho'); + } + + function test_getters() public view { + assertEq(stataTokenV2.name(), 'Static Aave Local WETH v2'); + assertEq(stataTokenV2.symbol(), 'stataLocWETHv2'); + + address referenceAsset = stataTokenV2.getReferenceAsset(); + assertEq(referenceAsset, aToken); + + address underlyingAddress = address(stataTokenV2.asset()); + assertEq(underlyingAddress, underlying); + + IERC20Metadata underlying = IERC20Metadata(underlyingAddress); + assertEq(stataTokenV2.decimals(), underlying.decimals()); + + assertEq( + address(stataTokenV2.INCENTIVES_CONTROLLER()), + address(AToken(aToken).getIncentivesController()) + ); + } +} diff --git a/tests/periphery/static-a-token/StataTokenV2Pausable.t.sol b/tests/periphery/static-a-token/StataTokenV2Pausable.t.sol index 1e714717..06d90b95 100644 --- a/tests/periphery/static-a-token/StataTokenV2Pausable.t.sol +++ b/tests/periphery/static-a-token/StataTokenV2Pausable.t.sol @@ -7,6 +7,15 @@ import {IERC4626StataToken} from '../../../src/periphery/contracts/static-a-toke import {BaseTest} from './TestBase.sol'; contract StataTokenV2PausableTest is BaseTest { + function test_canPause() external { + assertEq(stataTokenV2.canPause(poolAdmin), true); + } + + function test_canPause_shouldReturnFalse(address actor) external { + vm.assume(actor != poolAdmin); + assertEq(stataTokenV2.canPause(actor), false); + } + function test_setPaused_shouldRevertForInvalidCaller(address actor) external { vm.assume(actor != poolAdmin && actor != proxyAdmin); vm.expectRevert(abi.encodeWithSelector(IERC4626StataToken.OnlyPauseGuardian.selector, actor)); diff --git a/tests/periphery/static-a-token/StataTokenV2Permit.sol b/tests/periphery/static-a-token/StataTokenV2Permit.sol index 47829867..ebbe22e8 100644 --- a/tests/periphery/static-a-token/StataTokenV2Permit.sol +++ b/tests/periphery/static-a-token/StataTokenV2Permit.sol @@ -1,27 +1,83 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {IRescuable} from 'solidity-utils/contracts/utils/Rescuable.sol'; +import {ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol'; +import {SigUtils} from '../../utils/SigUtils.sol'; import {BaseTest} from './TestBase.sol'; -contract StataTokenV2RescuableTest is BaseTest { - function test_rescuable_shouldRevertForInvalidCaller() external { - deal(tokenList.usdx, address(stataTokenV2), 1 ether); - vm.expectRevert('ONLY_RESCUE_GUARDIAN'); - IRescuable(address(stataTokenV2)).emergencyTokenTransfer( - tokenList.usdx, - address(this), - 1 ether +contract StataTokenV2PermitTest is BaseTest { + function test_permit() public { + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: user, + spender: spender, + value: 1 ether, + nonce: stataTokenV2.nonces(user), + deadline: block.timestamp + 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + PERMIT_TYPEHASH, + stataTokenV2.DOMAIN_SEPARATOR() ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); + + stataTokenV2.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); + + assertEq(stataTokenV2.allowance(permit.owner, spender), permit.value); } - function test_rescuable_shouldSuceedForOwner() external { - deal(tokenList.usdx, address(stataTokenV2), 1 ether); - vm.startPrank(poolAdmin); - IRescuable(address(stataTokenV2)).emergencyTokenTransfer( - tokenList.usdx, - address(this), - 1 ether + function test_permit_expired() public { + // as the default timestamp is 0, we move ahead in time a bit + vm.warp(10 days); + + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: user, + spender: spender, + value: 1 ether, + nonce: stataTokenV2.nonces(user), + deadline: block.timestamp - 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + PERMIT_TYPEHASH, + stataTokenV2.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); + + vm.expectRevert( + abi.encodeWithSelector( + ERC20PermitUpgradeable.ERC2612ExpiredSignature.selector, + permit.deadline + ) + ); + stataTokenV2.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); + } + + function test_permit_invalidSigner() public { + SigUtils.Permit memory permit = SigUtils.Permit({ + owner: address(424242), + spender: spender, + value: 1 ether, + nonce: stataTokenV2.nonces(user), + deadline: block.timestamp + 1 days + }); + + bytes32 permitDigest = SigUtils.getTypedDataHash( + permit, + PERMIT_TYPEHASH, + stataTokenV2.DOMAIN_SEPARATOR() + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); + + vm.expectRevert( + abi.encodeWithSelector( + ERC20PermitUpgradeable.ERC2612InvalidSigner.selector, + user, + permit.owner + ) ); + stataTokenV2.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); } } diff --git a/tests/periphery/static-a-token/StataTokenV2Rescuable.sol b/tests/periphery/static-a-token/StataTokenV2Rescuable.sol index ebbe22e8..e43b14d8 100644 --- a/tests/periphery/static-a-token/StataTokenV2Rescuable.sol +++ b/tests/periphery/static-a-token/StataTokenV2Rescuable.sol @@ -1,83 +1,31 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.10; -import {ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol'; -import {SigUtils} from '../../utils/SigUtils.sol'; +import {IRescuable} from 'solidity-utils/contracts/utils/Rescuable.sol'; import {BaseTest} from './TestBase.sol'; -contract StataTokenV2PermitTest is BaseTest { - function test_permit() public { - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: user, - spender: spender, - value: 1 ether, - nonce: stataTokenV2.nonces(user), - deadline: block.timestamp + 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - PERMIT_TYPEHASH, - stataTokenV2.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); - - stataTokenV2.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); - - assertEq(stataTokenV2.allowance(permit.owner, spender), permit.value); +contract StataTokenV2RescuableTest is BaseTest { + function test_whoCanRescue() external view { + assertEq(IRescuable(address(stataTokenV2)).whoCanRescue(), poolAdmin); } - function test_permit_expired() public { - // as the default timestamp is 0, we move ahead in time a bit - vm.warp(10 days); - - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: user, - spender: spender, - value: 1 ether, - nonce: stataTokenV2.nonces(user), - deadline: block.timestamp - 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - PERMIT_TYPEHASH, - stataTokenV2.DOMAIN_SEPARATOR() + function test_rescuable_shouldRevertForInvalidCaller() external { + deal(tokenList.usdx, address(stataTokenV2), 1 ether); + vm.expectRevert('ONLY_RESCUE_GUARDIAN'); + IRescuable(address(stataTokenV2)).emergencyTokenTransfer( + tokenList.usdx, + address(this), + 1 ether ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); - - vm.expectRevert( - abi.encodeWithSelector( - ERC20PermitUpgradeable.ERC2612ExpiredSignature.selector, - permit.deadline - ) - ); - stataTokenV2.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); } - function test_permit_invalidSigner() public { - SigUtils.Permit memory permit = SigUtils.Permit({ - owner: address(424242), - spender: spender, - value: 1 ether, - nonce: stataTokenV2.nonces(user), - deadline: block.timestamp + 1 days - }); - - bytes32 permitDigest = SigUtils.getTypedDataHash( - permit, - PERMIT_TYPEHASH, - stataTokenV2.DOMAIN_SEPARATOR() - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, permitDigest); - - vm.expectRevert( - abi.encodeWithSelector( - ERC20PermitUpgradeable.ERC2612InvalidSigner.selector, - user, - permit.owner - ) + function test_rescuable_shouldSuceedForOwner() external { + deal(tokenList.usdx, address(stataTokenV2), 1 ether); + vm.startPrank(poolAdmin); + IRescuable(address(stataTokenV2)).emergencyTokenTransfer( + tokenList.usdx, + address(this), + 1 ether ); - stataTokenV2.permit(permit.owner, permit.spender, permit.value, permit.deadline, v, r, s); } } diff --git a/tests/periphery/static-a-token/StaticATokenNoLM.t.sol b/tests/periphery/static-a-token/StaticATokenNoLM.t.sol deleted file mode 100644 index 6f7bd5b2..00000000 --- a/tests/periphery/static-a-token/StaticATokenNoLM.t.sol +++ /dev/null @@ -1,51 +0,0 @@ -// // SPDX-License-Identifier: BUSL-1.1 -// pragma solidity ^0.8.10; - -// import {BaseTest, IERC20, IERC20AaveLM} from './TestBase.sol'; - -// /** -// * Testing the static token wrapper on a pool that never had LM enabled -// * This is a slightly different assumption than a pool that doesn't have LM enabled any more as incentivesController.rewardTokens() will have length=0 -// */ -// contract StaticATokenNoLMTest is BaseTest { -// function setUp() public override { -// super.setUp(); - -// vm.startPrank(user); -// } - -// // test rewards -// function test_collectAndUpdateRewardsWithLMDisabled() public { -// uint128 amountToDeposit = 5 ether; -// _fundUser(amountToDeposit, user); - -// _depositAToken(amountToDeposit, user); - -// _skipBlocks(60); -// assertEq(IERC20(REWARD_TOKEN).balanceOf(address(stataTokenV2)), 0); -// assertEq(stataTokenV2.getTotalClaimableRewards(REWARD_TOKEN), 0); -// assertEq(stataTokenV2.collectAndUpdateRewards(REWARD_TOKEN), 0); -// assertEq(IERC20(REWARD_TOKEN).balanceOf(address(stataTokenV2)), 0); -// } - -// function test_claimRewardsToSelfWithLMDisabled() public { -// uint128 amountToDeposit = 5 ether; -// _fundUser(amountToDeposit, user); - -// _depositAToken(amountToDeposit, user); - -// _skipBlocks(60); - -// vm.expectRevert( -// abi.encodeWithSelector(IERC20AaveLM.RewardNotInitialized.selector, REWARD_TOKEN) -// ); -// stataTokenV2.getClaimableRewards(user, REWARD_TOKEN); - -// vm.expectRevert( -// abi.encodeWithSelector(IERC20AaveLM.RewardNotInitialized.selector, REWARD_TOKEN) -// ); -// stataTokenV2.claimRewardsToSelf(rewardTokens); - -// assertEq(IERC20(REWARD_TOKEN).balanceOf(user), 0); -// } -// }