Skip to content

Commit

Permalink
fix: cleanup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sakulstra committed Aug 9, 2024
1 parent fd1c87a commit 7993e7c
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 429 deletions.
2 changes: 1 addition & 1 deletion src/periphery/contracts/static-a-token/StataOracle.sol
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
111 changes: 1 addition & 110 deletions src/periphery/contracts/static-a-token/StaticATokenLM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion tests/periphery/static-a-token/Pausable.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
45 changes: 44 additions & 1 deletion tests/periphery/static-a-token/Rewards.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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);
}
}
32 changes: 32 additions & 0 deletions tests/periphery/static-a-token/StataOracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

}
71 changes: 0 additions & 71 deletions tests/periphery/static-a-token/StaticATokenLM.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
*/
Expand Down
Loading

0 comments on commit 7993e7c

Please sign in to comment.