Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: ETH starter vault #7

Open
wants to merge 2 commits into
base: eth-starter-vault
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 4 additions & 40 deletions script/Actors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,26 @@ interface IActors {
function ADMIN() external view returns (address);
function UNAUTHORIZED() external view returns (address);
function PROPOSER_1() external view returns (address);
function PROPOSER_2() external view returns (address);
function EXECUTOR_1() external view returns (address);
function EXECUTOR_2() external view returns (address);
}

contract LocalActors is IActors {
address public constant ADMIN = address(1);
address public constant UNAUTHORIZED = address(3);

address public constant PROPOSER_1 = address(1);
address public constant PROPOSER_2 = address(2);

address public constant EXECUTOR_1 = address(3);
address public constant EXECUTOR_2 = address(4);
}

contract AnvilActors is IActors {
address public constant ADMIN = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address public constant UNAUTHORIZED = address(0);

address public constant PROPOSER_1 = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address public constant PROPOSER_2 = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;

address public constant EXECUTOR_1 = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address public constant EXECUTOR_2 = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;
}

contract HoleskyActors is IActors {
address public constant ADMIN = 0x743b91CDB1C694D4F51bCDA3a4A59DcC0d02b913;
address public constant UNAUTHORIZED = address(0);

address public constant PROPOSER_1 = 0x743b91CDB1C694D4F51bCDA3a4A59DcC0d02b913;
address public constant PROPOSER_2 = 0x9Dd8F69b62ddFd990241530F47dcEd0Dad7f7d39;

address public constant EXECUTOR_1 = 0x743b91CDB1C694D4F51bCDA3a4A59DcC0d02b913;
address public constant EXECUTOR_2 = 0x9Dd8F69b62ddFd990241530F47dcEd0Dad7f7d39;
}

contract ChapelActors is IActors {
address public constant ADMIN = 0x0c099101d43e9094E4ae9bC2FC38f8b9875c23c5;
address public constant UNAUTHORIZED = address(0);

address public constant PROPOSER_1 = 0x9f0A34ccb5ba9C71336F0c8Cd6181205928B8404;
address public constant PROPOSER_2 = 0x9f0A34ccb5ba9C71336F0c8Cd6181205928B8404;

address public constant EXECUTOR_1 = 0x9f0A34ccb5ba9C71336F0c8Cd6181205928B8404;
address public constant EXECUTOR_2 = 0x9f0A34ccb5ba9C71336F0c8Cd6181205928B8404;
}

contract BscActors is IActors {
address public constant ADMIN = 0x721688652DEa9Cabec70BD99411EAEAB9485d436;
contract MainnetActors is IActors {
address public constant ADMIN = 0xfcad670592a3b24869C0b51a6c6FDED4F95D6975;
address public constant UNAUTHORIZED = address(0);

address public constant PROPOSER_1 = 0x721688652DEa9Cabec70BD99411EAEAB9485d436;
address public constant PROPOSER_2 = 0x721688652DEa9Cabec70BD99411EAEAB9485d436;

address public constant EXECUTOR_1 = 0x721688652DEa9Cabec70BD99411EAEAB9485d436;
address public constant EXECUTOR_2 = 0x721688652DEa9Cabec70BD99411EAEAB9485d436;
address public constant PROPOSER_1 = 0xfcad670592a3b24869C0b51a6c6FDED4F95D6975;
address public constant EXECUTOR_1 = 0xfcad670592a3b24869C0b51a6c6FDED4F95D6975;
}
21 changes: 4 additions & 17 deletions script/Contracts.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

contract ChapelContracts {
address public constant ACTORS = 0xbA02225f0fdB684c80ad1e829FC31f048c416Ce6;
address public constant VAULT_FACTORY = 0x964C6d4050e052D627b8234CAD9CdF0981E40EB3;
address public constant SINGLE_VAULT = 0xa2aE2b28c578Fbd7C18B554E7aA388Bf6694a42c;
address public constant KERNEL_VAULT = address(0);
address public constant KARAK_KslisBNB = address(0);
address public constant KARAK_SUPERVISOR = address(0);
address public constant slisBNB = 0x80815ee920Bd9d856562633C36D3eB0E43cb15e2;
library HoleskyContracts {
address public constant WETH = 0x94373a4919B3240D86eA41593D5eBa789FEF3848;
}

contract BscContracts {
address public constant ACTORS = 0x1AA714a271047fA5AAFD190F084b66aA77Ba3562;
address public constant VAULT_FACTORY = 0xf6B9b69B7e13D37D3846698bA2625e404C7586aF;
address public constant SINGLE_VAULT = 0x40020796C11750975aD8758a1F2ab725f6b72Db2;
address public constant KERNEL_VAULT = address(0);
address public constant KARAK_KslisBNB = 0x8529019503c5BD707d8Eb98C5C87bF5237F89135;
address public constant KARAK_VAULT_SUPERVISOR = 0x4a2b015CcB8658998692Db9eD4522B8e846962eD;
address public constant slisBNB = 0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B;
address public constant ListaStakeManager = 0x1adB950d8bB3dA4bE104211D5AB038628e477fE6;
library MainnetContracts {
address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
}
43 changes: 15 additions & 28 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,51 @@ pragma solidity ^0.8.24;
import "lib/forge-std/src/Script.sol";

import {VaultFactory} from "src/VaultFactory.sol";
import {IVaultFactory} from "src/IVaultFactory.sol";
import {AnvilActors, HoleskyActors, ChapelActors, BscActors, IActors} from "script/Actors.sol";
import {IVaultFactory} from "src/interface/IVaultFactory.sol";
import {IActors, MainnetActors, HoleskyActors} from "script/Actors.sol";
import {MainnetContracts, HoleskyContracts} from "script/Contracts.sol";
import {SingleVault} from "src/SingleVault.sol";
import {TransparentUpgradeableProxy, TimelockController} from "src/Common.sol";

contract DeployVaultFactory is Script {
function run() public {
if (block.chainid == 31337) {
vm.startBroadcast();
AnvilActors actors = new AnvilActors();
uint256 minDelay = 10; // seconds
deployVaultFactory(actors, minDelay);
}

if (block.chainid == 17000) {
vm.startBroadcast();
HoleskyActors actors = new HoleskyActors();
uint256 minDelay = 10; // seconds
deployVaultFactory(actors, minDelay);
}

if (block.chainid == 97) {
vm.startBroadcast();
ChapelActors actors = new ChapelActors();
uint256 minDelay = 10; // seconds
deployVaultFactory(actors, minDelay);
address weth = HoleskyContracts.WETH;
deployVaultFactory(actors, minDelay, weth);
}

if (block.chainid == 56) {
if (block.chainid == 1 || block.chainid == 31337) {
vm.startBroadcast();
BscActors actors = new BscActors();
uint256 minDelay = 86400; // 24 hours in seconds
deployVaultFactory(actors, minDelay);
MainnetActors actors = new MainnetActors();
uint256 minDelay = 86400; // seconds
address weth = MainnetContracts.WETH;
deployVaultFactory(actors, minDelay, weth);
}
}

function deployVaultFactory(IActors actors, uint256 minDelay) public returns (address) {
function deployVaultFactory(IActors actors, uint256 minDelay, address weth) public returns (address) {
address vaultFactoryImpl = address(new VaultFactory());
address singleVaultImpl = address(new SingleVault());

address[] memory proposers = new address[](2);
address[] memory proposers = new address[](1);
proposers[0] = actors.PROPOSER_1();
proposers[1] = actors.PROPOSER_2();

address[] memory executors = new address[](2);
address[] memory executors = new address[](1);
executors[0] = actors.EXECUTOR_1();
executors[1] = actors.EXECUTOR_2();

address admin = actors.ADMIN();

string memory funcSig = "initialize(address,address,address)";
string memory funcSig = "initialize(address,address,address,address)";

TimelockController timelock = new TimelockController(minDelay, proposers, executors, admin);

TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
vaultFactoryImpl,
address(timelock),
abi.encodeWithSignature(funcSig, singleVaultImpl, admin, address(timelock))
abi.encodeWithSignature(funcSig, singleVaultImpl, admin, address(timelock), weth)
);
return address(proxy);
}
Expand Down
23 changes: 0 additions & 23 deletions src/ISingleVault.sol

This file was deleted.

45 changes: 0 additions & 45 deletions src/IVaultFactory.sol

This file was deleted.

101 changes: 33 additions & 68 deletions src/SingleVault.sol
Original file line number Diff line number Diff line change
@@ -1,99 +1,64 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

import {
ERC4626Upgradeable,
ReentrancyGuardUpgradeable,
TimelockControllerUpgradeable,
IERC20,
IERC4626,
IStakeManager,
Math
} from "src/Common.sol";
import {ERC4626Upgradeable, AccessControlUpgradeable, ReentrancyGuardUpgradeable, IERC20, Math} from "src/Common.sol";

import {ISingleVault} from "src/ISingleVault.sol";
import {ISingleVault} from "src/interface/ISingleVault.sol";

contract SingleVault is ISingleVault, ERC4626Upgradeable, TimelockControllerUpgradeable, ReentrancyGuardUpgradeable {
using Math for uint256;
/* ynETH Pre-Launch Vault */

bytes32 private constant ERC4626StorageLocation = 0x0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e00;
IStakeManager private constant stakeManager = IStakeManager(0x1adB950d8bB3dA4bE104211D5AB038628e477fE6);
contract SingleVault is ISingleVault, ERC4626Upgradeable, AccessControlUpgradeable, ReentrancyGuardUpgradeable {
using Math for uint256;

constructor() {
_disableInitializers();
}

/**
* @dev Initializes the SingleVault contract.
* @param asset_ The address of the ERC20 asset.
* @param name_ The name of the vault.
* @param symbol_ The symbol of the vault.
* @param admin_ The address of the admin.
* @param minDelay_ The minimum delay for timelock.
* @param proposers_ The addresses of the proposers.
* @param executors_ The addresses of the executors.
*/
function initialize(
IERC20 asset_,
string memory name_,
string memory symbol_,
address admin_,
uint256 minDelay_,
address[] calldata proposers_,
address[] calldata executors_
) public initializer {
_verifyParamsAreValid(asset_, name_, symbol_, admin_, proposers_, executors_);
__TimelockController_init(minDelay_, proposers_, executors_, admin_);
function initialize(IERC20 asset_, string memory name_, string memory symbol_, address admin_) public initializer {
_verifyParamsAreValid(asset_, name_, symbol_, admin_);
__ERC20_init(name_, symbol_);
__ERC4626_init(asset_);
__AccessControl_init();
__ReentrancyGuard_init();
_grantRole(DEFAULT_ADMIN_ROLE, admin_);
}

function _verifyParamsAreValid(
IERC20 asset_,
string memory name_,
string memory symbol_,
address admin_,
address[] calldata proposers_,
address[] calldata executors_
) internal pure {
if (asset_ == IERC20(address(0))) revert AssetZeroAddress();
if (bytes(name_).length == 0) revert NameEmpty();
if (bytes(symbol_).length == 0) revert SymbolEmpty();
if (admin_ == address(0)) revert AdminZeroAddress();
if (proposers_.length == 0) revert ProposersEmpty();
if (executors_.length == 0) revert ExecutorsEmpty();
receive() external payable nonReentrant {
if (msg.value > 0) {
_mintSharesForETH(msg.value);
}
}

function _retrieveERC4626Storage() internal pure returns (ERC4626Storage storage $) {
assembly {
$.slot := ERC4626StorageLocation
fallback() external payable nonReentrant {
if (msg.value > 0) {
_mintSharesForETH(msg.value);
}
}

function totalAssets() public view override(ERC4626Upgradeable, IERC4626) returns (uint256) {
ERC4626Storage storage $ = _retrieveERC4626Storage();
uint256 assetBalance = $._asset.balanceOf(address(this));
return _convertSnBnbToBnb(assetBalance);
}
function _mintSharesForETH(uint256 amount) private {
IERC20 weth = _retrieveERC4626Storage()._asset;

function _convertSnBnbToBnb(uint256 amount) internal view returns (uint256) {
return stakeManager.convertSnBnbToBnb(amount);
}
(bool success,) = address(weth).call{value: amount}("");
if (!success) revert DepositFailed();

function _convertBnbToSnBnb(uint256 amount) internal view returns (uint256) {
return stakeManager.convertBnbToSnBnb(amount);
if (msg.sender != address(this)) {
_mint(msg.sender, amount);
}
}

function _convertToShares(uint256 assets, Math.Rounding rounding) internal view override returns (uint256) {
uint256 bnbAssets = _convertSnBnbToBnb(assets);
return bnbAssets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);
function _verifyParamsAreValid(IERC20 asset_, string memory name_, string memory symbol_, address admin_)
internal
pure
{
if (asset_ == IERC20(address(0))) revert AssetZeroAddress();
if (bytes(name_).length == 0) revert NameEmpty();
if (bytes(symbol_).length == 0) revert SymbolEmpty();
if (admin_ == address(0)) revert AdminZeroAddress();
}

function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view override returns (uint256) {
uint256 bnbShares = shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding);
return _convertBnbToSnBnb(bnbShares);
function _retrieveERC4626Storage() internal pure returns (ERC4626Storage storage $) {
assembly {
$.slot := 0x0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e00
}
}
}
Loading