From 2e08235398bb7b62f932dd40239afcc65ff612af Mon Sep 17 00:00:00 2001 From: Pablo Veyrat Date: Thu, 23 May 2024 18:20:46 +0200 Subject: [PATCH] finish savings tests --- contracts/savings/Savings.sol | 2 +- test/fuzz/SavingsNameableTest.t.sol | 127 ++++++++++++++++++ ...t.sol => SavingsNameableUpgradeTest.t.sol} | 80 ++++------- 3 files changed, 155 insertions(+), 54 deletions(-) create mode 100644 test/fuzz/SavingsNameableTest.t.sol rename test/units/upgrade/{SavingsNameable.t.sol => SavingsNameableUpgradeTest.t.sol} (81%) diff --git a/contracts/savings/Savings.sol b/contracts/savings/Savings.sol index c15d19d5..1d4c6209 100644 --- a/contracts/savings/Savings.sol +++ b/contracts/savings/Savings.sol @@ -32,7 +32,7 @@ contract Savings is BaseSavings { /// @notice Checks whether the address is trusted to set the rate mapping(address => uint256) public isTrustedUpdater; - uint256[49] private __gap; + uint256[48] private __gap; /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EVENTS diff --git a/test/fuzz/SavingsNameableTest.t.sol b/test/fuzz/SavingsNameableTest.t.sol new file mode 100644 index 00000000..ef220e7d --- /dev/null +++ b/test/fuzz/SavingsNameableTest.t.sol @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import { SafeERC20 } from "oz/token/ERC20/utils/SafeERC20.sol"; +import { IERC20Metadata } from "../mock/MockTokenPermit.sol"; +import "../Fixture.sol"; +import "../utils/FunctionUtils.sol"; +import "contracts/utils/Errors.sol" as Errors; +import "contracts/savings/nameable/SavingsNameable.sol"; +import { UD60x18, ud, pow, powu, unwrap } from "prb/math/UD60x18.sol"; + +import { stdError } from "forge-std/Test.sol"; + +contract SavingsNameableTest is Fixture, FunctionUtils { + using SafeERC20 for IERC20; + + uint256 internal constant _initDeposit = 1e12; + SavingsNameable internal _saving; + Savings internal _savingImplementation; + string internal _name; + string internal _symbol; + + function setUp() public override { + super.setUp(); + + _savingImplementation = new SavingsNameable(); + bytes memory data; + _saving = SavingsNameable(_deployUpgradeable(address(proxyAdmin), address(_savingImplementation), data)); + _name = "Staked EURA"; + _symbol = "stEUR"; + + vm.startPrank(governor); + agToken.addMinter(address(_saving)); + deal(address(agToken), governor, _initDeposit); + agToken.approve(address(_saving), _initDeposit); + _saving.initialize( + accessControlManager, + IERC20MetadataUpgradeable(address(agToken)), + _name, + _symbol, + BASE_18 / _initDeposit + ); + _saving.setMaxRate(type(uint256).max); + vm.stopPrank(); + } + + function test_Initialization() public { + assertEq(address(_saving.accessControlManager()), address(accessControlManager)); + assertEq(_saving.asset(), address(agToken)); + assertEq(_saving.name(), _name); + assertEq(_saving.symbol(), _symbol); + assertEq(_saving.totalAssets(), _initDeposit); + assertEq(_saving.totalSupply(), _initDeposit); + assertEq(agToken.balanceOf(address(_saving)), _initDeposit); + assertEq(_saving.balanceOf(address(governor)), 0); + assertEq(_saving.balanceOf(address(_saving)), _initDeposit); + } + + function test_Initialize() public { + // To have the test written at least once somewhere + assert(accessControlManager.isGovernor(governor)); + assert(accessControlManager.isGovernorOrGuardian(guardian)); + assert(accessControlManager.isGovernorOrGuardian(governor)); + bytes memory data; + Savings savingsContract = Savings( + _deployUpgradeable(address(proxyAdmin), address(_savingImplementation), data) + ); + Savings savingsContract2 = Savings( + _deployUpgradeable(address(proxyAdmin), address(_savingImplementation), data) + ); + + vm.startPrank(governor); + agToken.addMinter(address(savingsContract)); + deal(address(agToken), governor, _initDeposit * 10); + agToken.approve(address(savingsContract), _initDeposit); + agToken.approve(address(savingsContract2), _initDeposit); + + savingsContract.initialize( + accessControlManager, + IERC20MetadataUpgradeable(address(agToken)), + _name, + _symbol, + BASE_18 / _initDeposit + ); + + vm.expectRevert(); + savingsContract.initialize( + accessControlManager, + IERC20MetadataUpgradeable(address(agToken)), + _name, + _symbol, + BASE_18 / _initDeposit + ); + + vm.expectRevert(Errors.ZeroAddress.selector); + savingsContract2.initialize( + IAccessControlManager(address(0)), + IERC20MetadataUpgradeable(address(agToken)), + _name, + _symbol, + BASE_18 / _initDeposit + ); + + vm.stopPrank(); + + assertEq(address(savingsContract.accessControlManager()), address(accessControlManager)); + assertEq(savingsContract.asset(), address(agToken)); + assertEq(savingsContract.name(), _name); + assertEq(savingsContract.symbol(), _symbol); + assertEq(savingsContract.totalAssets(), _initDeposit); + assertEq(savingsContract.totalSupply(), _initDeposit); + assertEq(agToken.balanceOf(address(savingsContract)), _initDeposit); + assertEq(savingsContract.balanceOf(address(governor)), 0); + assertEq(savingsContract.balanceOf(address(savingsContract)), _initDeposit); + } + + function test_SetNameAndSymbol() public { + vm.expectRevert(Errors.NotGovernor.selector); + _saving.setNameAndSymbol("EURA Test", "EURA"); + + vm.startPrank(governor); + _saving.setNameAndSymbol("EURA Test", "EURA"); + assertEq(_saving.name(), "EURA Test"); + assertEq(_saving.symbol(), "EURA"); + vm.stopPrank(); + } +} diff --git a/test/units/upgrade/SavingsNameable.t.sol b/test/units/upgrade/SavingsNameableUpgradeTest.t.sol similarity index 81% rename from test/units/upgrade/SavingsNameable.t.sol rename to test/units/upgrade/SavingsNameableUpgradeTest.t.sol index 491fc90e..b0cbff4f 100644 --- a/test/units/upgrade/SavingsNameable.t.sol +++ b/test/units/upgrade/SavingsNameableUpgradeTest.t.sol @@ -9,7 +9,7 @@ import { ProxyAdmin } from "oz/proxy/transparent/ProxyAdmin.sol"; import { IERC20Metadata } from "oz/interfaces/IERC20Metadata.sol"; import { TransparentUpgradeableProxy } from "oz/proxy/transparent/TransparentUpgradeableProxy.sol"; -contract SavingsNameableTest is Test, Helper { +contract SavingsNameableUpgradeTest is Test, Helper { uint256 constant CHAIN = CHAIN_ETHEREUM; string constant CHAIN_NAME = "mainnet"; @@ -26,12 +26,27 @@ contract SavingsNameableTest is Test, Helper { uint256 public previewMint; uint256 public previewWithdraw; uint256 public previewRedeem; + address public governor; + address public guardian; + ProxyAdmin public proxyAdmin; function setUp() public { vm.createSelectFork(CHAIN_NAME); savings = _chainToContract(CHAIN, ContractType.StUSD); + if (CHAIN == CHAIN_BASE || CHAIN == CHAIN_POLYGONZKEVM) + proxyAdmin = ProxyAdmin(_chainToContract(CHAIN, ContractType.ProxyAdminGuardian)); + else proxyAdmin = ProxyAdmin(_chainToContract(CHAIN, ContractType.ProxyAdmin)); + governor = _chainToContract(CHAIN, ContractType.GovernorMultisig); + guardian = _chainToContract(CHAIN, ContractType.GuardianMultisig); + + // TODO: to be removed when chainToContract works + savings = 0x0022228a2cc5E7eF0274A7Baa600d44da5aB5776; + proxyAdmin = ProxyAdmin(0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b); + governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8; + guardian = 0x0C2553e4B9dFA9f83b1A6D3EAB96c4bAaB42d430; + assertEq(IERC20Metadata(savings).name(), "Staked USDA"); assertEq(IERC20Metadata(savings).symbol(), "stUSD"); rate = SavingsNameable(savings).rate(); @@ -46,70 +61,29 @@ contract SavingsNameableTest is Test, Helper { previewRedeem = SavingsNameable(savings).previewRedeem(BASE_18); savingsImpl = address(new SavingsNameable()); + _upgradeContract("Staked USDA", "stUSD"); } function _upgradeContract(string memory name, string memory symbol) internal { - ProxyAdmin proxyAdmin; - if (CHAIN == CHAIN_BASE || CHAIN == CHAIN_POLYGONZKEVM) - proxyAdmin = ProxyAdmin(_chainToContract(CHAIN, ContractType.ProxyAdminGuardian)); - else proxyAdmin = ProxyAdmin(_chainToContract(CHAIN, ContractType.ProxyAdmin)); - - address governor = _chainToContract(CHAIN, ContractType.GovernorMultisig); - address guardian = _chainToContract(CHAIN, ContractType.GuardianMultisig); - - // vm.prank(guardian, guardian); if (CHAIN == CHAIN_BASE || CHAIN == CHAIN_POLYGONZKEVM) vm.prank(guardian, guardian); else vm.prank(governor, governor); proxyAdmin.upgrade(TransparentUpgradeableProxy(payable(savings)), savingsImpl); - vm.prank(governor, governor); SavingsNameable(savings).setNameAndSymbol(name, symbol); } - function test_NameAndSymbol() public { - _upgradeContract("Staked USDA", "stUSD"); - + function test_UpdatedValues() public { assertEq(IERC20Metadata(savings).name(), "Staked USDA"); assertEq(IERC20Metadata(savings).symbol(), "stUSD"); - } - - function test_Rate() public { - assertEq(SavingsNameable(savings).rate(), rate); - } - - function test_LastUpdate() public { - assertEq(SavingsNameable(savings).lastUpdate(), lastUpdate); - } - - function test_Paused() public { - assertEq(SavingsNameable(savings).paused(), paused); - } - - function test_MaxRate() public { - assertEq(SavingsNameable(savings).maxRate(), maxRate); - } - - function test_TotalSupply() public { - assertEq(SavingsNameable(savings).totalSupply(), totalSupply); - } - - function test_TotalAssets() public { - assertEq(SavingsNameable(savings).totalAssets(), totalAssets); - } - - function test_PreviewDeposit() public { - assertEq(SavingsNameable(savings).previewDeposit(BASE_18), previewDeposit); - } - - function test_PreviewMint() public { - assertEq(SavingsNameable(savings).previewMint(BASE_18), previewMint); - } - - function test_PreviewWithdraw() public { - assertEq(SavingsNameable(savings).previewWithdraw(BASE_18), previewWithdraw); - } - - function test_PreviewRedeem() public { assertEq(SavingsNameable(savings).previewRedeem(BASE_18), previewRedeem); + assertEq(SavingsNameable(savings).previewWithdraw(BASE_18), previewWithdraw); + assertEq(SavingsNameable(savings).previewMint(BASE_18), previewMint); + assertEq(SavingsNameable(savings).previewDeposit(BASE_18), previewDeposit); + assertEq(SavingsNameable(savings).totalAssets(), totalAssets); + assertEq(SavingsNameable(savings).totalSupply(), totalSupply); + assertEq(SavingsNameable(savings).maxRate(), maxRate); + assertEq(SavingsNameable(savings).paused(), paused); + assertEq(SavingsNameable(savings).lastUpdate(), lastUpdate); + assertEq(SavingsNameable(savings).rate(), rate); } }