Skip to content

Commit

Permalink
forge fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
xhad committed Sep 13, 2024
1 parent 88a4d93 commit cb57f84
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 6 deletions.
15 changes: 15 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "solhint:recommended",
"plugins": [],
"rules": {
"avoid-suicide": "error",
"avoid-sha3": "warn",
"compiler-version": ["error", "^0.8.0"],
"func-visibility": ["warn", { "ignoreConstructors": true }],
"reason-string": ["warn", { "maxLength": 64 }],
"not-rely-on-time": "warn",
"state-visibility": "error",
"max-line-length": ["warn", 120],
"no-console": "off"
}
}
7 changes: 1 addition & 6 deletions src/VaultFactory.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

import {
AccessControlUpgradeable,
TransparentUpgradeableProxy,
IERC20,
IERC4626
} from "src/Common.sol";
import {AccessControlUpgradeable, TransparentUpgradeableProxy, IERC20, IERC4626} from "src/Common.sol";

import {IVaultFactory} from "src/IVaultFactory.sol";

Expand Down
12 changes: 12 additions & 0 deletions test/mocks/MockSingleVault.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

import {SingleVault} from "src/SingleVault.sol";

contract MockSingleVault is SingleVault {
constructor() {
_disableInitializers();
}

uint256 public constant R_TWO_D = 2;
}
86 changes: 86 additions & 0 deletions test/single/unit/invariants.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

import {SingleVault} from "src/SingleVault.sol";
import {MockERC20} from "test/mocks/MockERC20.sol";
import {Math} from "src/Common.sol";
import {SetupHelper} from "test/helpers/Setup.sol";
import {Etches} from "test/helpers/Etches.sol";
import {TestConstants} from "test/helpers/Constants.sol";
import {LocalActors} from "script/Actors.sol";

import "forge-std/Test.sol";

contract SingleInvariantTests is Test, LocalActors, TestConstants {
using Math for uint256;

SingleVault public vault;
MockERC20 public asset;
address USER = address(33);

function setUp() public {
vm.startPrank(ADMIN);
asset = MockERC20(address(new MockERC20(ASSET_NAME, ASSET_SYMBOL)));

Etches etches = new Etches();
etches.mockListaStakeManager();

SetupHelper setup = new SetupHelper();
vault = setup.createVault(asset);
}

event Log(uint256 amount, string name);

function test_totalAssetsAlwaysCorrect(uint256 depositAmount) public {
if (depositAmount < 1) return;
if (depositAmount > 1e50) return;

uint256 initialTotalAssets = vault.totalAssets();
depositHelper(USER, depositAmount);
uint256 currentTotalAssets = vault.totalAssets();
uint256 expectedDepositAssets = vault.previewDeposit(depositAmount);
uint256 expectedAssets = initialTotalAssets + expectedDepositAssets;
assertClose(currentTotalAssets, expectedAssets, 10, "Total assets mismatch after deposit");
}

function test_totalSupplyAlwaysCorrect(uint256 depositAmount) public {
if (depositAmount < 1) return;
if (depositAmount > 1e50) return;

uint256 initialTotalSupply = vault.totalSupply();
depositHelper(USER, depositAmount);
uint256 currentTotalSupply = vault.totalSupply();
uint256 expectedDepositAssets = vault.previewDeposit(depositAmount);
uint256 expectedSupply = initialTotalSupply + expectedDepositAssets;
assertClose(currentTotalSupply, expectedSupply, 1, "Total supply mismatch after deposit");
}

function test_totalSupplyMatchesBalances(uint256 depositAmount) public {
if (depositAmount < 2) return;
if (depositAmount > 1e50) return;

depositHelper(USER, depositAmount);
uint256 total = vault.totalSupply();
assertEq(vault.convertToShares(depositAmount + 1 ether), total, "Total supply does not balances");
}

function test_conversionConsistency(uint256 depositAmount) public view {
if (depositAmount < 2) return;
if (depositAmount > 1e50) return;
uint256 shares = vault.convertToShares(depositAmount);
uint256 convertedAssets = vault.convertToAssets(shares);
assertClose(depositAmount, convertedAssets, 1, "Conversion inconsistency");
}

function depositHelper(address user, uint256 depositAmount) public {
vm.startPrank(user);
asset.mint(depositAmount);
asset.approve(address(vault), depositAmount);
vault.deposit(depositAmount, address(this));
vm.stopPrank();
}

function assertClose(uint256 actual, uint256 expected, uint256 delta, string memory message) internal pure {
require(actual >= expected - delta && actual <= expected + delta, message);
}
}
76 changes: 76 additions & 0 deletions test/single/unit/upgrade.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// BSD 3-Clause License
pragma solidity ^0.8.24;

import {SingleVault} from "src/SingleVault.sol";
import {MockERC20} from "test/mocks/MockERC20.sol";
import {SetupHelper} from "test/helpers/Setup.sol";
import {Etches} from "test/helpers/Etches.sol";
import {LocalActors} from "script/Actors.sol";
import {TestConstants} from "test/helpers/Constants.sol";
import {IERC20} from "src/Common.sol";
import {IVaultFactory} from "src/IVaultFactory.sol";
import {MockSingleVault} from "test/mocks/MockSingleVault.sol";
import {TimelockController} from "src/Common.sol";

import "forge-std/Test.sol";

contract SingleVaultUpgradeTests is Test, LocalActors, TestConstants {
SingleVault public vault;
MockERC20 public asset;
IVaultFactory public factory;

function setUp() public {
vm.startPrank(ADMIN);
asset = MockERC20(address(new MockERC20(ASSET_NAME, ASSET_SYMBOL)));

Etches etches = new Etches();
etches.mockListaStakeManager();

SetupHelper setup = new SetupHelper();
vault = setup.createVault(asset);

factory = IVaultFactory(setup.factory());
}

function testUpgrade() public {
vm.startPrank(ADMIN);
SingleVault newVault = new MockSingleVault();

// the timelock on the factory is the admin for proxy upgrades
TimelockController timelock = TimelockController(payable(factory.timelock()));

// schedule a proxy upgrade transaction on the timelock
// the traget is the proxy admin, created by foundry test
address target = 0xF094c1B2ec3E52f6D02603C4dB28dd4Ba0067048;
uint256 value = 0;

bytes4 selector = bytes4(keccak256("upgradeAndCall(address,address,bytes)"));

bytes memory data = abi.encodeWithSelector(selector, address(vault), address(newVault), "");

bytes32 predecessor = bytes32(0);
bytes32 salt = keccak256("chad");

uint256 delay = 1;
vm.startPrank(PROPOSER_1);
timelock.schedule(target, value, data, predecessor, salt, delay);
vm.stopPrank();

bytes32 id = keccak256(abi.encode(target, value, data, predecessor, salt));
assert(timelock.getOperationState(id) == TimelockController.OperationState.Waiting);

assertEq(timelock.isOperationReady(id), false);
assertEq(timelock.isOperationDone(id), false);
assertEq(timelock.isOperation(id), true);

//execute the transaction
vm.warp(500);
vm.startPrank(EXECUTOR_1);
timelock.execute(target, value, data, predecessor, salt);

// Verify the transaction was executed successfully
assertEq(timelock.isOperationReady(id), false);
assertEq(timelock.isOperationDone(id), true);
assert(timelock.getOperationState(id) == TimelockController.OperationState.Done);
}
}

0 comments on commit cb57f84

Please sign in to comment.