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

vault deploy jobs #107

Merged
merged 1 commit into from
Nov 22, 2024
Merged
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
54 changes: 54 additions & 0 deletions .github/workflows/deploy-sepolia-vault-governance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: "[sepolia-deploy] deploy governance for vault"
on:
workflow_dispatch:
inputs:
proposer:
description: 'Proposer address'
required: true
default: '0x'
vault:
description: 'Vault Address'
required: true
default: '0x'
accountant:
description: 'Accountant Address'
required: true
default: '0x'
governorRoleAddress:
description: 'Governor role address'
required: true
default: '0x'
governorVaults:
description: 'Governor vaults as comma separated'
required: false
default: ''
Comment on lines +5 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve input parameter validation and documentation

The input parameters need better validation and documentation:

  1. The default value '0x' is not a valid Ethereum address
  2. Consider adding a pattern for validating Ethereum addresses
  3. Specify whether addresses should be checksummed or lowercase

Apply this diff to improve the input configuration:

       proposer:
         description: 'Proposer address'
         required: true
-        default: '0x'
+        default: '0x0000000000000000000000000000000000000000'
+        pattern: '^0x[a-fA-F0-9]{40}$'
       vault:
         description: 'Vault Address'
         required: true
-        default: '0x'
+        default: '0x0000000000000000000000000000000000000000'
+        pattern: '^0x[a-fA-F0-9]{40}$'
       accountant:
         description: 'Accountant Address'
         required: true
-        default: '0x'
+        default: '0x0000000000000000000000000000000000000000'
+        pattern: '^0x[a-fA-F0-9]{40}$'
       governorRoleAddress:
         description: 'Governor role address'
         required: true
-        default: '0x'
+        default: '0x0000000000000000000000000000000000000000'
+        pattern: '^0x[a-fA-F0-9]{40}$'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
proposer:
description: 'Proposer address'
required: true
default: '0x'
vault:
description: 'Vault Address'
required: true
default: '0x'
accountant:
description: 'Accountant Address'
required: true
default: '0x'
governorRoleAddress:
description: 'Governor role address'
required: true
default: '0x'
governorVaults:
description: 'Governor vaults as comma separated'
required: false
default: ''
proposer:
description: 'Proposer address'
required: true
default: '0x0000000000000000000000000000000000000000'
pattern: '^0x[a-fA-F0-9]{40}$'
vault:
description: 'Vault Address'
required: true
default: '0x0000000000000000000000000000000000000000'
pattern: '^0x[a-fA-F0-9]{40}$'
accountant:
description: 'Accountant Address'
required: true
default: '0x0000000000000000000000000000000000000000'
pattern: '^0x[a-fA-F0-9]{40}$'
governorRoleAddress:
description: 'Governor role address'
required: true
default: '0x0000000000000000000000000000000000000000'
pattern: '^0x[a-fA-F0-9]{40}$'
governorVaults:
description: 'Governor vaults as comma separated'
required: false
default: ''


jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: sepolia
url: https://term-finance.github.io/yearn-v3-term-vault/
steps:
- uses: actions/checkout@master
with:
fetch-depth: 0
submodules: recursive
- uses: foundry-rs/foundry-toolchain@v1
- run: forge install
- run: forge build
- run: forge tree
- run: forge script script/VaultGovernanceDeploy.s.sol:VaultGovernanceDeploy --rpc-url $RPC_URL --broadcast --gas-price 500000000000 --verify --verbosity 4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix script arguments and consider dynamic gas pricing

  1. Add quotes around script arguments to prevent word splitting
  2. Consider using dynamic gas pricing instead of hardcoded value

Apply this diff:

-      - run: forge script script/VaultGovernanceDeploy.s.sol:VaultGovernanceDeploy --rpc-url $RPC_URL --broadcast --gas-price  500000000000   --verify --verbosity 4
+      - run: forge script "script/VaultGovernanceDeploy.s.sol:VaultGovernanceDeploy" --rpc-url "$RPC_URL" --broadcast --verify --verbosity 4

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 actionlint (1.7.3)

41-41: shellcheck reported issue in this script: SC2086:info:1:81: Double quote to prevent globbing and word splitting

(shellcheck)

env:
RPC_URL: ${{ secrets.RPC_URL }}
PRIVATE_KEY: ${{ secrets.GOVERNANCE_DEPLOYER_KEY }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}
PROPOSER: ${{ github.event.inputs.proposer }}
VAULT: ${{ github.event.inputs.vault }}
ACCOUNTANT: ${{ github.event.inputs.accountant }}
GOVERNOR: ${{ github.event.inputs.governorRoleAddress }}
GOVERNANCE_FACTORY: ${{ vars.GOVERNANCE_FACTORY }}

Comment on lines +42 to +51
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add environment variable verification

Consider adding a step to verify that all required environment variables are set before proceeding with deployment.

Add this step before the forge script:

      - name: Verify environment variables
        run: |
          required_vars=("RPC_URL" "PRIVATE_KEY" "ETHERSCAN_API_KEY" "GOVERNANCE_FACTORY")
          for var in "${required_vars[@]}"; do
            if [ -z "${!var}" ]; then
              echo "Error: Required environment variable $var is not set"
              exit 1
            fi
          done
🧰 Tools
🪛 yamllint (1.29.0-1)

[warning] 43-43: too many spaces after colon

(colons)




34 changes: 22 additions & 12 deletions .github/workflows/deploy-sepolia-vault.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,24 @@ on:
description: 'Profit max unlock time'
required: true
default: '0'
roleManager:
description: 'Role Manager'
depositLimit:
description: 'Deposit limit'
required: false
default: '0x'
roleNumber:
description: 'sum of roles'
default: '0'
defaultRefund:
description: 'Default refund'
required: false
default: '0'
depositLimit:
description: 'Deposit limit'
defaultMaxFee:
description: 'Default max fee'
required: false
default: '0'
defaultMaxGain:
description: 'Default max gain'
required: false
default: '0'
defaultMaxLoss:
description: 'Default max loss'
required: false
default: '0'

Expand Down Expand Up @@ -57,12 +65,14 @@ jobs:
ACCOUNTANT_FACTORY: ${{ vars.ACCOUNTANT_FACTORY }}
VAULT_NAME: ${{ github.event.inputs.vaultName }}
VAULT_SYMBOL: ${{ github.event.inputs.vaultSymbol }}
FEE_MANAGER: ${{ vars.FEE_MANAGER }}
FEE_RECIPIENT: ${{ vars.FEE_RECIPIENT }}
DEPOSIT_LIMIT: ${{ github.event.inputs.depositLimit }}
IS_TEST: true
ROLE_MANAGER: ${{ github.event.inputs.roleManager }}
ROLE_NUM: ${{ github.event.inputs.roleNumber }}
VAULT_GOVERNANCE_FACTORY: ${{ vars.VAULT_GOVERNANCE_FACTORY }}
KEEPER: ${{ vars.KEEPER }}
PROFIT_MAX_UNLOCK_TIME: ${{ github.event.inputs.profitMaxUnlockTime }}
ADMIN_ADDRESS: ${{ vars.ADMIN_ADDRESS }}
DEFAULT_REFUND: ${{ github.event.inputs.defaultRefund }}
DEFAULT_MAX_FEE: ${{ github.event.inputs.defaultMaxFee }}
DEFAULT_MAX_GAIN: ${{ github.event.inputs.defaultMaxGain }}
DEFAULT_MAX_LOSS: ${{ github.event.inputs.defaultMaxLoss }}


4 changes: 2 additions & 2 deletions script/DeployGovernance.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.18;
import "forge-std/Script.sol";
import "../src/Strategy.sol";

interface TermVaultGovernanceFactory {
interface TermStrategyGovernanceFactory {
function deploySafe(
address proposer,
address strategy,
Expand Down Expand Up @@ -109,7 +109,7 @@ contract DeployGovernance is Script {

vm.startBroadcast(deployerPK);

TermVaultGovernanceFactory factory = TermVaultGovernanceFactory(vm.envAddress("GOVERNANCE_FACTORY"));
TermStrategyGovernanceFactory factory = TermStrategyGovernanceFactory(vm.envAddress("GOVERNANCE_FACTORY"));
address proposer = vm.envAddress("PROPOSER");
address strategy = vm.envAddress("STRATEGY");
address governor = vm.envAddress("GOVERNOR");
Expand Down
34 changes: 34 additions & 0 deletions script/VaultGovernanceDeploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "forge-std/Script.sol";

interface TermVaultGovernanceFactory {
function deploySafe(
address proposer,
address vault,
address accountant,
address governor
) external;
}

contract VaultGovernanceDeploy is Script {
function run() external {
uint256 deployerPK = vm.envUint("PRIVATE_KEY");

// Set up the RPC URL (optional if you're using the default foundry config)
string memory rpcUrl = vm.envString("RPC_URL");

Comment on lines +18 to +20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove unused RPC URL configuration.

The RPC URL is read from environment variables but never used. This could mislead users into thinking it affects the deployment.

-        // Set up the RPC URL (optional if you're using the default foundry config)
-        string memory rpcUrl = vm.envString("RPC_URL");
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Set up the RPC URL (optional if you're using the default foundry config)
string memory rpcUrl = vm.envString("RPC_URL");

vm.startBroadcast(deployerPK);

TermVaultGovernanceFactory factory = TermVaultGovernanceFactory(vm.envAddress("GOVERNANCE_FACTORY"));
address proposer = vm.envAddress("PROPOSER");
address vault = vm.envAddress("VAULT");
address accountant = vm.envAddress("ACCOUNTANT");
address governor = vm.envAddress("GOVERNOR");

factory.deploySafe(proposer, vault, accountant, governor);
Comment on lines +23 to +29
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add input validation for critical addresses.

The script should validate that all addresses are non-zero and that required environment variables exist.

+        function _validateAddress(address addr, string memory name) internal pure {
+            require(addr != address(0), string.concat(name, " address cannot be zero"));
+        }
+
         TermVaultGovernanceFactory factory = TermVaultGovernanceFactory(vm.envAddress("GOVERNANCE_FACTORY"));
+        _validateAddress(address(factory), "Factory");
+
         address proposer = vm.envAddress("PROPOSER");
+        _validateAddress(proposer, "Proposer");
+
         address vault = vm.envAddress("VAULT");
+        _validateAddress(vault, "Vault");
+
         address accountant = vm.envAddress("ACCOUNTANT");
+        _validateAddress(accountant, "Accountant");
+
         address governor = vm.envAddress("GOVERNOR");
+        _validateAddress(governor, "Governor");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TermVaultGovernanceFactory factory = TermVaultGovernanceFactory(vm.envAddress("GOVERNANCE_FACTORY"));
address proposer = vm.envAddress("PROPOSER");
address vault = vm.envAddress("VAULT");
address accountant = vm.envAddress("ACCOUNTANT");
address governor = vm.envAddress("GOVERNOR");
factory.deploySafe(proposer, vault, accountant, governor);
function _validateAddress(address addr, string memory name) internal pure {
require(addr != address(0), string.concat(name, " address cannot be zero"));
}
TermVaultGovernanceFactory factory = TermVaultGovernanceFactory(vm.envAddress("GOVERNANCE_FACTORY"));
_validateAddress(address(factory), "Factory");
address proposer = vm.envAddress("PROPOSER");
_validateAddress(proposer, "Proposer");
address vault = vm.envAddress("VAULT");
_validateAddress(vault, "Vault");
address accountant = vm.envAddress("ACCOUNTANT");
_validateAddress(accountant, "Accountant");
address governor = vm.envAddress("GOVERNOR");
_validateAddress(governor, "Governor");
factory.deploySafe(proposer, vault, accountant, governor);


vm.stopBroadcast();
Comment on lines +29 to +31
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add deployment success verification.

The script should verify that the safe deployment was successful.

         factory.deploySafe(proposer, vault, accountant, governor);
+        
+        // Verify deployment success by checking the deployed safe address
+        // Note: This requires adding a view function to the factory interface
+        address deployedSafe = factory.getLastDeployedSafe();
+        require(deployedSafe != address(0), "Safe deployment failed");
+        console.log("Safe deployed at:", deployedSafe);

         vm.stopBroadcast();

Committable suggestion skipped: line range outside the PR's diff.

}

}
78 changes: 51 additions & 27 deletions script/VaultManagement.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ contract SetupVaultManagement is Script {
// Set up the RPC URL (optional if you're using the default foundry config)
string memory rpcUrl = vm.envString("RPC_URL");

address deployer = vm.addr(deployerPK);

vm.startBroadcast(deployerPK);

// Retrieve environment variables
Expand All @@ -22,48 +24,70 @@ contract SetupVaultManagement is Script {
address asset = vm.envAddress("ASSET_ADDRESS");
string memory name = vm.envString("VAULT_NAME");
string memory symbol = vm.envString("VAULT_SYMBOL");
address roleManager = vm.envAddress("ROLE_MANAGER");
uint256 profitMaxUnlockTime = vm.envUint("PROFIT_MAX_UNLOCK_TIME");
address feeManager = vm.envAddress("FEE_MANAGER");
address feeRecipient = vm.envAddress("FEE_RECIPIENT");
uint256 depositLimit = vm.envOr("DEPOSIT_LIMIT",uint256(0));

address admin = vm.envAddress("ADMIN_ADDRESS");
uint256 roleNum = vm.envOr("ROLE_NUM", uint(256));
bool isTest = vm.envBool("IS_TEST");
address vaultGovernanceFactory = vm.envAddress("VAULT_GOVERNANCE_FACTORY");

IVaultFactory vaultFactory = IVaultFactory(vaultFactoryAddress);
address vaultAddress = vaultFactory.deploy_new_vault(asset, name, symbol, roleManager, profitMaxUnlockTime);
address vaultAddress = vaultFactory.deploy_new_vault(asset, name, symbol, deployer, profitMaxUnlockTime);
IVault vault = IVault(vaultAddress);
console.log("deployed vault contract to");
console.log(address(vault));

AccountantFactory accountantFactory = AccountantFactory(accountantFactoryAddress);
address accountantAddress = accountantFactory.newAccountant(feeManager, feeRecipient);
address accountantAddress = accountantFactory.newAccountant();
Accountant accountant = Accountant(accountantAddress);
console.log("deployed accountant contract to");
console.log(address(accountant));

if (isTest) {
vault.set_role(admin, roleNum);
console.log("set role for admin");
console.log(roleNum);
_setVaultParams(vault, accountantAddress, vaultGovernanceFactory);
_setAccountantParams(accountant, vaultGovernanceFactory);

vault.set_accountant(address(accountant));
console.log("set accountant for vault");
console.log(address(accountant));
vm.stopBroadcast();
}

function _setVaultParams(IVault vault, address accountant, address vaultGovernanceFactory) internal {
uint256 depositLimit = vm.envOr("DEPOSIT_LIMIT",uint256(0));
address keeper = vm.envAddress("KEEPER_ADDRESS");

vault.set_deposit_limit(depositLimit);
console.log("set deposit limit");
console.log(depositLimit);
vault.set_role(keeper, 112);
console.log("set role for keeper");

vault.set_use_default_queue(true);
console.log("set use default queue to true");
vault.set_auto_allocate(true);
console.log("set auto allocate to true");
}

vm.stopBroadcast();
vault.set_accountant(accountant);
console.log("set accountant for vault");
console.log(accountant);

vault.set_deposit_limit(depositLimit);
console.log("set deposit limit");
console.log(depositLimit);

vault.set_use_default_queue(true);
console.log("set use default queue to true");
vault.set_auto_allocate(true);
console.log("set auto allocate to true");

vault.transfer_role_manager(vaultGovernanceFactory);
vault.accept_role_manager();
}

function _setAccountantParams(Accountant accountant, address vaultGovernanceFactory) internal {
uint16 defaultManagement = uint16(vm.envOr("DEFAULT_MANAGEMENT", uint256(0)));
uint16 defaultPerformance = uint16(vm.envOr("DEFAULT_PERFORMANCE", uint256(0)));
uint16 defaultRefund = uint16(vm.envOr("DEFAULT_REFUND", uint256(0)));
uint16 defaultMaxFee = uint16(vm.envOr("DEFAULT_MAX_FEE", uint256(0)));
uint16 defaultMaxGain = uint16(vm.envOr("DEFAULT_MAX_GAIN", uint256(0)));
uint16 defaultMaxLoss = uint16(vm.envOr("DEFAULT_MAX_LOSS", uint256(0)));
address newFeeRecipient = vm.envAddress("FEE_RECIPIENT");

accountant.updateDefaultConfig(defaultManagement, defaultPerformance, defaultRefund, defaultMaxFee, defaultMaxGain, defaultMaxLoss);
console.log("set default config for accountant");
console.log(defaultManagement);
console.log(defaultPerformance);
console.log(defaultRefund);
console.log(defaultMaxFee);
console.log(defaultMaxGain);
console.log(defaultMaxLoss);

accountant.setFutureFeeManager(vaultGovernanceFactory);
accountant.setFeeRecipient(newFeeRecipient);
}
}