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

update deployment from scratch #441

Merged
merged 14 commits into from
Jan 8, 2023
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
9 changes: 8 additions & 1 deletion SCRATCH_DEPLOY.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ Steps for deploy:
* [ ] deploy Lido Apps repo contracts (via Lido Template)
* [ ] deploy Lido DAO contract (via Lido Template)
* [ ] issue DAO tokens (via Lido Template)
* [ ] deploy LidoExecutionLayerRewardsVault
* [ ] finalize DAO setup (via Lido Template)
* [ ] deploy CompositePostRebaseBeaconReceiver
* [ ] deploy SelfOwnedStETHBurner
* [ ] do Aragon voting to attach CompositePostRebaseBeaconReceiver and SelfOwnedStETHBurner to the protocol
* [ ] make final deployed DAO check via script
* [ ] open and check Lido DAO web interface (via Aragon client)

Expand All @@ -69,11 +73,14 @@ So, one-click local deploy from scratch command is:

## Aragon dependency issue

`ipfs-http-client` version has been strictly pinned to `43.0.0` in [this commit](https://github.com/lidofinance/lido-dao/commit/38bf0232fbc59ec6d69d27e170e3e75cfbe1ba11) because `/scripts/multisig/04-publish-app-frontends.js` used to crash at
`ipfs-http-client` version has been strictly pinned to `43.0.0` in [this commit](https://github.com/lidofinance/lido-dao/commit/38bf0232fbc59ec6d69d27e170e3e75cfbe1ba11) because `/scripts/multisig/04-publish-app-frontends.js` used to crash at
```javascript
const rootCid = await uploadDirToIpfs({ dirPath: distPath, ipfsApiUrl: ipfsAPI })
```

It appeared that `@aragon/buidler-aragon@npm:^0.2.9` uses `ipfs-http-client`.

`ipfs-http-client` has a brittle API. Neither `41.0.0` nor `50.0.0` versions of it will work with `@aragon/buidler-aragon@npm:^0.2.9`.

## Default Aragon voting time
To attach SelfOwnedStETHBurner to the protocol a DAO voting is needed. To do it reasonably fast on the protocol deployment the default Aragon voting duration time (see `deployed-local-defaults.json`) is set to seconds. Draft script for changing Aragon voting time is at `scripts/multisig/32-change-voting-time.js`.
18 changes: 2 additions & 16 deletions contracts/0.4.24/template/Imports.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,8 @@

pragma solidity 0.4.24;

import "@aragon/os/contracts/acl/ACL.sol";
import "@aragon/os/contracts/kernel/Kernel.sol";
import "@aragon/os/contracts/factory/DAOFactory.sol";
import "@aragon/os/contracts/factory/APMRegistryFactory.sol";
import "@aragon/os/contracts/factory/ENSFactory.sol";
import "@aragon/os/contracts/apm/APMRegistry.sol";
import "@aragon/os/contracts/apm/Repo.sol";
import "@aragon/os/contracts/ens/ENSSubdomainRegistrar.sol";
import "@aragon/os/contracts/lib/ens/ENS.sol";
import "@aragon/os/contracts/lib/ens/AbstractENS.sol";
import "@aragon/os/contracts/lib/ens/PublicResolver.sol";
import "@aragon/id/contracts/FIFSResolvingRegistrar.sol";

import "@aragon/apps-vault/contracts/Vault.sol";
import "@aragon/apps-voting/contracts/Voting.sol";
import "@aragon/apps-finance/contracts/Finance.sol";
import "@aragon/apps-token-manager/contracts/TokenManager.sol";

// Needed just to trigger generation of the compilation artifacts
// missing otherwise
contract Imports {} /* solium-disable-line no-empty-blocks */
46 changes: 31 additions & 15 deletions contracts/0.4.24/template/LidoTemplate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import "@aragon/os/contracts/common/IsContract.sol";

import "@aragon/apps-agent/contracts/Agent.sol";
import "@aragon/apps-vault/contracts/Vault.sol";
import "@aragon/apps-voting/contracts/Voting.sol";

import "@aragon/apps-lido/apps/voting/contracts/Voting.sol";

import "@aragon/apps-finance/contracts/Finance.sol";
import "@aragon/apps-token-manager/contracts/TokenManager.sol";
import "@aragon/apps-shared-minime/contracts/MiniMeToken.sol";
import "@aragon/apps-lido/apps/token-manager/contracts/TokenManager.sol";

import "@aragon/id/contracts/IFIFSResolvingRegistrar.sol";

Expand All @@ -31,7 +32,7 @@ import "../interfaces/IDepositContract.sol";


contract LidoTemplate is IsContract {
// Configurarion errors
// Configuration errors
string constant private ERROR_ZERO_OWNER = "TMPL_ZERO_OWNER";
string constant private ERROR_ENS_NOT_CONTRACT = "TMPL_ENS_NOT_CONTRACT";
string constant private ERROR_DAO_FACTORY_NOT_CONTRACT = "TMPL_DAO_FAC_NOT_CONTRACT";
Expand Down Expand Up @@ -298,7 +299,7 @@ contract LidoTemplate is IsContract {
function newDAO(
string _tokenName,
string _tokenSymbol,
uint64[3] _votingSettings,
uint64[4] _votingSettings,
IDepositContract _beaconDepositContract,
uint32[4] _beaconSpec
)
Expand Down Expand Up @@ -334,9 +335,10 @@ contract LidoTemplate is IsContract {
state.lidoRegistryEnsNode,
state.dao,
state.token,
_votingSettings[0],
_votingSettings[1],
_votingSettings[2]
_votingSettings[0], // support
_votingSettings[1], // acceptance
_votingSettings[2], // duration
_votingSettings[3] // objectionPhaseDuration
);

bytes memory noInit = new bytes(0);
Expand Down Expand Up @@ -380,7 +382,7 @@ contract LidoTemplate is IsContract {
);

// used for issuing vested tokens in the next step
_createTokenManagerPersissionsForTemplate(state.acl, state.tokenManager);
_createTokenManagerPermissionsForTemplate(state.acl, state.tokenManager);

emit TmplDAOAndTokenDeployed(address(state.dao), address(state.token));

Expand Down Expand Up @@ -426,7 +428,9 @@ contract LidoTemplate is IsContract {
uint16 _treasuryFeeBP,
uint16 _insuranceFeeBP,
uint16 _operatorsFeeBP,
uint256 _unvestedTokensAmount
uint256 _unvestedTokensAmount,
address _elRewardsVault,
uint16 _elRewardsWithdrawalLimit
)
onlyOwner
external
Expand All @@ -444,6 +448,17 @@ contract LidoTemplate is IsContract {
state.lido.setFeeDistribution(_treasuryFeeBP, _insuranceFeeBP, _operatorsFeeBP);
_removePermissionFromTemplate(state.acl, state.lido, LIDO_MANAGE_FEE);

// Set Execution Layer rewards parameters on Lido contract
bytes32 LIDO_SET_EL_REWARDS_VAULT = state.lido.SET_EL_REWARDS_VAULT_ROLE();
_createPermissionForTemplate(state.acl, state.lido, LIDO_SET_EL_REWARDS_VAULT);
state.lido.setELRewardsVault(_elRewardsVault);
_removePermissionFromTemplate(state.acl, state.lido, LIDO_SET_EL_REWARDS_VAULT);

bytes32 LIDO_SET_EL_REWARDS_WITHDRAWAL_LIMIT = state.lido.SET_EL_REWARDS_WITHDRAWAL_LIMIT_ROLE();
_createPermissionForTemplate(state.acl, state.lido, LIDO_SET_EL_REWARDS_WITHDRAWAL_LIMIT);
state.lido.setELRewardsWithdrawalLimit(_elRewardsWithdrawalLimit);
_removePermissionFromTemplate(state.acl, state.lido, LIDO_SET_EL_REWARDS_WITHDRAWAL_LIMIT);

if (_unvestedTokensAmount != 0) {
// using issue + assign to avoid setting the additional MINT_ROLE for the template
state.tokenManager.issue(_unvestedTokensAmount);
Expand Down Expand Up @@ -517,12 +532,13 @@ contract LidoTemplate is IsContract {
MiniMeToken _token,
uint64 _support,
uint64 _acceptance,
uint64 _duration
uint64 _duration,
uint64 _objectionPhaseDuration
)
private returns (Voting)
{
bytes32 appId = _getAppId(ARAGON_VOTING_APP_NAME, _lidoRegistryEnsNode);
bytes memory initializeData = abi.encodeWithSelector(Voting(0).initialize.selector, _token, _support, _acceptance, _duration);
bytes memory initializeData = abi.encodeWithSelector(Voting(0).initialize.selector, _token, _support, _acceptance, _duration, _objectionPhaseDuration);
return Voting(_installNonDefaultApp(_dao, appId, initializeData));
}

Expand Down Expand Up @@ -553,7 +569,7 @@ contract LidoTemplate is IsContract {
uint64 _vestingCliff,
uint64 _vestingEnd,
bool _vestingRevokable,
uint256 _extectedFinalTotalSupply
uint256 _expectedFinalTotalSupply
)
private
returns (uint256 totalAmount)
Expand All @@ -566,7 +582,7 @@ contract LidoTemplate is IsContract {
}

_tokenManager.issue(totalAmount);
require(_token.totalSupply() == _extectedFinalTotalSupply, ERROR_UNEXPECTED_TOTAL_SUPPLY);
require(_token.totalSupply() == _expectedFinalTotalSupply, ERROR_UNEXPECTED_TOTAL_SUPPLY);

for (i = 0; i < _holders.length; ++i) {
_tokenManager.assignVested(_holders[i], _amounts[i], _vestingStart, _vestingCliff, _vestingEnd, _vestingRevokable);
Expand Down Expand Up @@ -665,7 +681,7 @@ contract LidoTemplate is IsContract {
}
}

function _createTokenManagerPersissionsForTemplate(ACL _acl, TokenManager _tokenManager) internal {
function _createTokenManagerPermissionsForTemplate(ACL _acl, TokenManager _tokenManager) internal {
_createPermissionForTemplate(_acl, _tokenManager, _tokenManager.ISSUE_ROLE());
_createPermissionForTemplate(_acl, _tokenManager, _tokenManager.ASSIGN_ROLE());
}
Expand Down
35 changes: 16 additions & 19 deletions dao-local-deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ set -o pipefail
# first local account by default
DEPLOYER=${DEPLOYER:=0xb4124cEB3451635DAcedd11767f004d8a28c6eE7}
NETWORK=${NETWORK:=local}
ARAGON_APPS_REPO_REF=import-shared-minime

VOTE_ID=0
echo "DEPLOYER is $DEPLOYER"
echo "NETWORK is $NETWORK"

function msg() {
MSG=$1
Expand All @@ -28,10 +30,11 @@ docker-compose down -v
docker-compose up --build -d

rm -f deployed-$NETWORK.json
cp deployed-local-defaults.json deployed-$NETWORK.json
cp deployed-$NETWORK-defaults.json deployed-$NETWORK.json

yarn install --immutable
yarn compile

yarn deploy:$NETWORK:aragon-env
msg "Aragon ENV deployed."
yarn deploy:$NETWORK:aragon-std-apps
Expand Down Expand Up @@ -68,7 +71,7 @@ yarn hardhat --network $NETWORK run ./scripts/multisig/06-obtain-deployed-apm.js
msg "APM deployed"

yarn hardhat --network $NETWORK run ./scripts/multisig/07-create-app-repos.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-04-create-app-repos.json
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-07-create-app-repos.json
msg "App repos created"

yarn hardhat --network $NETWORK run ./scripts/multisig/08-deploy-dao.js
Expand All @@ -80,6 +83,13 @@ yarn hardhat --network $NETWORK run ./scripts/multisig/10-issue-tokens.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-06-1-issue-tokens.json
msg "Tokens issued"

# Execution Layer Rewards: deploy the vault
yarn hardhat --network $NETWORK run ./scripts/multisig/26-deploy-execution-layer-rewards-vault.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-26-deploy-execution-layer-rewards-vault.json
pause "!!! Now set the executionLayerRewardsVaultDeployTx hash value in deployed-$NETWORK.json"
yarn hardhat --network $NETWORK run ./scripts/multisig/27-obtain-deployed-execution-layer-rewards-vault.js
msg "ExecutionLayerRewardsVault deployed"

yarn hardhat --network $NETWORK run ./scripts/multisig/11-finalize-dao.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-11-finalize-dao.json
msg "DAO deploy finalized"
Expand All @@ -101,23 +111,10 @@ msg "SelfOwnedStETHBurner deployed"
# Insurance: attach the contracts to the protocol
yarn hardhat --network $NETWORK run ./scripts/multisig/25-vote-self-owned-steth-burner.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-25-vote-self-owned-steth-burner.json
VOTE_ID=$VOTE_ID yarn hardhat --network $NETWORK run ./scripts/multisig/vote-and-enact.js
msg "Vote $VOTE_ID executed"
VOTE_ID=$((VOTE_ID+1))

# Execution Layer Rewards: deploy
yarn hardhat --network $NETWORK run ./scripts/multisig/26-deploy-execution-layer-rewards-vault.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-26-deploy-execution-layer-rewards-vault.json
pause "!!! Now set the executionLayerRewardsVaultDeployTx hash value in deployed-$NETWORK.json"
yarn hardhat --network $NETWORK run ./scripts/multisig/27-obtain-deployed-execution-layer-rewards-vault.js
msg "ExecutionLayerRewardsVault deployed"
yarn hardhat --network $NETWORK run ./scripts/multisig/vote-and-enact.js
msg "Vote for attaching the insurance module is executed"

# Execution Layer Rewards: attach the contracts to the protocol
yarn hardhat --network $NETWORK run ./scripts/multisig/28-vote-el-rewards.js
yarn hardhat --network $NETWORK tx --from $DEPLOYER --file tx-28-vote-el-rewards.json
VOTE_ID=$VOTE_ID yarn hardhat --network $NETWORK run ./scripts/multisig/vote-and-enact.js
msg "Vote $VOTE_ID executed"
VOTE_ID=$((VOTE_ID+1))
# MAYBE TODO: Create and auto execute vote to increase vote time (like 10+5 minute)

# Check the deployed protocol
yarn hardhat --network $NETWORK run ./scripts/multisig/12-check-dao.js
Expand Down
6 changes: 5 additions & 1 deletion deployed-local-defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"voting": {
"minSupportRequired": "500000000000000000",
"minAcceptanceQuorum": "50000000000000000",
"voteDuration": 14400
"voteDuration": 30,
"objectionPhaseDuration": 1
},
"beaconSpec": {
"depositContractAddress": "",
Expand Down Expand Up @@ -51,5 +52,8 @@
"totalCoverSharesBurnt": "0",
"totalNonCoverSharesBurnt": "0",
"maxBurnAmountPerRunBasisPoints": "4"
},
"executionLayerRewardsParams": {
"withdrawalLimit": "1"
}
}
Loading