Skip to content

Commit

Permalink
feat: upgrade to new staked token (#4)
Browse files Browse the repository at this point in the history
* feat: deploy first oracle

* fix: update imports

* fix: add new stake-token

* fix: upgrade code

* fix: update tests

* fix: use addresses from address book

* fix: use aave from address book

* fix: update to latest version

* Update src/libs/GenericProposal.sol

* Apply suggestions from code review

Co-authored-by: Ernesto Boado <ebdmrr@gmail.com>

* Update src/contracts/StkABPTMigrator.sol

Co-authored-by: Ernesto Boado <ebdmrr@gmail.com>

* fix: use selector

* fix: remove comment

* fix: remove proportional migration

* fix: add balance checks to prevent draining donation

* fix: use executor-lvl1 as referral

* fix: remove duplicate import

* fix: remove unused import

* fix: add a few more migration tests

* fix: add emission end

* Update scripts/01_DeployStkAbptV2Impl.sol

Co-authored-by: Ernesto Boado <ebdmrr@gmail.com>

* fix: use default create

---------

Co-authored-by: Ernesto Boado <ebdmrr@gmail.com>
  • Loading branch information
sakulstra and eboadom committed Jan 18, 2024
1 parent a369cee commit ce20220
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 286 deletions.
10 changes: 3 additions & 7 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/aave-address-book"]
path = lib/aave-address-book
url = https://github.com/bgd-labs/aave-address-book
[submodule "lib/aave-helpers"]
path = lib/aave-helpers
url = https://github.com/bgd-labs/aave-helpers
Expand All @@ -14,7 +11,6 @@
path = lib/stk-no-cooldown
url = https://github.com/bgd-labs/aave-stk-v1-5
branch = feat/post-slashing
[submodule "lib/aave-stk-gov-v3"]
path = lib/aave-stk-gov-v3
url = https://github.com/bgd-labs/aave-stk-gov-v3
branch = feat/new-deployment
[submodule "lib/stake-token"]
path = lib/stake-token
url = https://github.com/bgd-labs/stake-token
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ update:; forge update
build :; forge build --sizes
test :; forge test -vvv

deploy-ledger :; forge script ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x25F2226B597E8F9514B3F68F00f494cF4f286491 -vvvv,--broadcast --ledger --mnemonics foo --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv)
deploy-ledger :; forge script ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x25F2226B597E8F9514B3F68F00f494cF4f286491 -vvvv,--broadcast --ledger --mnemonics foo --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv --resume)

# Utilities
download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address}
Expand Down Expand Up @@ -39,3 +39,5 @@ diff-snapshot :
npm run clean-storage-report noCooldownStakedToken
make git-diff before=reports/currentStakedToken.md after=reports/newStakedToken.md out=NewVersion_storageDiff.md
make git-diff before=reports/currentStakedToken.md after=reports/noCooldownStakedToken.md out=NoCooldown_storageDiff.md

deploy-oracles-ledger :; make deploy-ledger contract=scripts/00_PriceOracles.s.sol:DeployOracles chain=mainnet
1 change: 0 additions & 1 deletion lib/aave-address-book
Submodule aave-address-book deleted from b87a51
2 changes: 1 addition & 1 deletion lib/aave-helpers
Submodule aave-helpers updated 214 files
1 change: 0 additions & 1 deletion lib/aave-stk-gov-v3
Submodule aave-stk-gov-v3 deleted from 748cde
1 change: 1 addition & 0 deletions lib/stake-token
Submodule stake-token added at f42de8
14 changes: 7 additions & 7 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
aave-address-book/=lib/aave-address-book/src/
aave-address-book/=lib/aave-helpers/lib/aave-address-book/src/
aave-helpers/=lib/aave-helpers/src/
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
forge-std/=lib/aave-helpers/lib/forge-std/src/
solidity-utils/=lib/solidity-utils/src/
aave-v3-periphery/=lib/aave-v3-periphery/contracts/
aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/
aave-stk-gov-v3/=lib/aave-stk-gov-v3/src/
aave-v3-periphery/=lib/aave-helpers/lib/aave-v3-periphery/contracts/
aave-v3-core/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-core/
stake-token/=lib/stake-token/src/
stk-no-cooldown/=lib/stk-no-cooldown/src/
aave-token-v3/=lib/aave-stk-gov-v3/lib/aave-token-v3/src
openzeppelin-contracts/=lib/aave-stk-gov-v3/lib/aave-token-v3/lib/openzeppelin-contracts
aave-token-v3/=lib/stake-token/lib/aave-token-v3/src
openzeppelin-contracts/=lib/stake-token/lib/openzeppelin-contracts
43 changes: 20 additions & 23 deletions scripts/01_DeployStkAbptV2Impl.sol
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveMisc} from 'aave-address-book/AaveMisc.sol';
import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol';
import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {EthereumScript} from 'aave-helpers/ScriptUtils.sol';
import {StakedTokenV3 as StakedTokenV3NoCooldown, IERC20 as IERC20NoCooldown} from 'stk-no-cooldown/contracts/StakedTokenV3.sol';
import {StakedTokenV3} from 'aave-stk-gov-v3/contracts/StakedTokenV3.sol';
import {StakeToken} from 'stake-token/contracts/StakeToken.sol';
import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol';
import {IWeightedPool} from '../src/interfaces/IWeightedPool.sol';
import {GenericProposal} from '../src/libs/GenericProposal.sol';
import {Addresses} from '../src/libs/Addresses.sol';

/**
* This is an completely empty contract.
* It just exists to initialize Proxies with "some implementation"
*/
contract PlaceholderContract {

}

/**
* @notice Deploys a the implementation for the pool with the bricked initialize.
*/
contract DeployImpl is EthereumScript {
function _deploy() public returns (address, address, address) {
function _deploy() public returns (address, address) {
address stkABPTV2Impl = address(
new StakedTokenV3(
new StakeToken(
'stk AAVE/wstETH BPTv2',
IERC20(Addresses.ABPT_V2),
IERC20(AaveV3EthereumAssets.AAVE_UNDERLYING),
GenericProposal.UNSTAKE_WINDOW,
GenericProposal.REWARDS_VAULT,
GenericProposal.EMISSION_MANAGER,
GenericProposal.DISTRIBUTION_DURATION
GenericProposal.EMISSION_MANAGER
)
);

address tokenProxy = ITransparentProxyFactory(AaveMisc.TRANSPARENT_PROXY_FACTORY_ETHEREUM)
.createDeterministic(
address(new PlaceholderContract()),
AaveMisc.PROXY_ADMIN_ETHEREUM,
bytes(''),
'ABPT_V2'
);
address tokenProxy = ITransparentProxyFactory(MiscEthereum.TRANSPARENT_PROXY_FACTORY).create(
address(stkABPTV2Impl),
MiscEthereum.PROXY_ADMIN,
abi.encodeWithSelector(
StakeToken.initialize.selector,
'stk AAVE/wstETH BPTv2', // name
'stkAAVEwstETHBPTv2', // symbol
GenericProposal.SLASHING_ADMIN,
GenericProposal.COOLDOWN_ADMIN,
GenericProposal.CLAIM_HELPER,
GenericProposal.MAX_SLASHING,
GenericProposal.COOLDOWN_SECONDS
)
);

return (
address(
Expand All @@ -56,7 +54,6 @@ contract DeployImpl is EthereumScript {
GenericProposal.DISTRIBUTION_DURATION
)
),
stkABPTV2Impl,
tokenProxy
);
}
Expand Down
12 changes: 3 additions & 9 deletions scripts/02_DeployPayload.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,14 @@ import {ProposalPayload} from '../src/contracts/ProposalPayload.sol';
*/
contract DeployPayload is EthereumScript {
address internal constant STK_ABPT_V1_IMPL = address(0);
address internal constant STK_ABPT_V2_IMPL = address(0);

function _deploy(
address stkAbptV1Impl,
address stkAbptV2Impl,
address stkAbptV2Proxy
) public returns (address) {
function _deploy(address stkAbptV1Impl, address stkAbptV2Proxy) public returns (address) {
require(stkAbptV1Impl != address(0));
require(stkAbptV2Impl != address(0));
require(stkAbptV2Proxy != address(0));
return address(new ProposalPayload(stkAbptV1Impl, stkAbptV2Impl, stkAbptV2Proxy));
return address(new ProposalPayload(stkAbptV1Impl, stkAbptV2Proxy));
}

function run() external broadcast {
_deploy(STK_ABPT_V1_IMPL, STK_ABPT_V2_IMPL, address(0));
_deploy(STK_ABPT_V1_IMPL, address(0));
}
}
79 changes: 38 additions & 41 deletions src/contracts/ProposalPayload.sol
Original file line number Diff line number Diff line change
@@ -1,82 +1,79 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {AaveMisc} from 'aave-address-book/AaveMisc.sol';
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol';
import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol';
import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol';
import {GenericProposal} from '../libs/GenericProposal.sol';
import {DistributionTypes} from 'aave-stk-gov-v3/lib/DistributionTypes.sol';
import {IAaveDistributionManager} from 'aave-stk-gov-v3/interfaces/IAaveDistributionManager.sol';
import {Vault} from '../interfaces/Actions.sol';
import {Addresses} from '../libs/Addresses.sol';
import {DistributionTypes} from 'stake-token/contracts/lib/DistributionTypes.sol';
import {IAaveDistributionManager} from 'stake-token/contracts/IAaveDistributionManager.sol';
import {IAggregatedStakeToken} from 'stake-token/contracts/IAggregatedStakeToken.sol';
import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveSafetyModule} from 'aave-address-book/AaveSafetyModule.sol';

/**
* @title StkABPTV2 Proposal
* @author BGD Labs
* @notice migrates emissions to a new stkABPT
*/
contract ProposalPayload {
address public constant AAVE = Addresses.AAVE;
address public constant WSTETH = Addresses.WSTETH;
address public constant STK_ABPT_V1 = Addresses.STK_ABPT_V1;
Vault public constant VAULT = Vault(Addresses.BALANCER_VAULT);
uint256 public constant EMISSION_PER_SECOND = 4456018518518518; // same as current

address public immutable STK_ABPT_V1_IMPL;
address public immutable STK_ABPT_V2_IMPL;
address public immutable STK_ABPT_V2_PROXY;

constructor(address newStkABPTV1Impl, address newStkABPTV2Impl, address stkABPTV2Proxy) {
constructor(address newStkABPTV1Impl, address stkABPTV2Proxy) {
STK_ABPT_V1_IMPL = newStkABPTV1Impl;
STK_ABPT_V2_IMPL = newStkABPTV2Impl;
STK_ABPT_V2_PROXY = stkABPTV2Proxy;
}

function execute() external {
// 1. stop emission on module v1
// 1. disable cooldown by upgrading the impl
ProxyAdmin(MiscEthereum.PROXY_ADMIN).upgradeAndCall(
TransparentUpgradeableProxy(payable(AaveSafetyModule.STK_ABPT)),
STK_ABPT_V1_IMPL,
abi.encodeWithSignature('initialize()')
);

// 2. stop emission on module v1
DistributionTypes.AssetConfigInput[]
memory disableConfigs = new DistributionTypes.AssetConfigInput[](1);
disableConfigs[0] = DistributionTypes.AssetConfigInput({
emissionPerSecond: 0,
totalStaked: 0, // it's overwritten internally
underlyingAsset: STK_ABPT_V1
underlyingAsset: AaveSafetyModule.STK_ABPT
});
IAaveDistributionManager(STK_ABPT_V1).configureAssets(disableConfigs);

// 2. disable cooldown by upgrading the impl
ProxyAdmin(AaveMisc.PROXY_ADMIN_ETHEREUM).upgradeAndCall(
TransparentUpgradeableProxy(payable(STK_ABPT_V1)),
STK_ABPT_V1_IMPL,
abi.encodeWithSignature('initialize()')
IAaveDistributionManager(AaveSafetyModule.STK_ABPT).configureAssets(disableConfigs);
MiscEthereum.AAVE_ECOSYSTEM_RESERVE_CONTROLLER.approve(
MiscEthereum.ECOSYSTEM_RESERVE,
AaveV3EthereumAssets.AAVE_UNDERLYING,
AaveSafetyModule.STK_ABPT,
0
);

// 3. create new SM
ProxyAdmin(AaveMisc.PROXY_ADMIN_ETHEREUM).upgradeAndCall(
TransparentUpgradeableProxy(payable(STK_ABPT_V2_PROXY)),
STK_ABPT_V2_IMPL,
abi.encodeWithSignature(
'initialize(address,address,address,uint256,uint256)',
GenericProposal.SLASHING_ADMIN,
GenericProposal.COOLDOWN_ADMIN,
GenericProposal.CLAIM_HELPER,
GenericProposal.MAX_SLASHING,
GenericProposal.COOLDOWN_SECONDS
)
MiscEthereum.AAVE_ECOSYSTEM_RESERVE_CONTROLLER.approve(
MiscEthereum.ECOSYSTEM_RESERVE,
AaveV3EthereumAssets.AAVE_UNDERLYING,
AaveSafetyModule.STK_ABPT,
15_000 ether // rough estimation on total claimable + emission until execution
);

// 4. start emission on module v2
AaveMisc.AAVE_ECOSYSTEM_RESERVE_CONTROLLER.approve(
AaveMisc.ECOSYSTEM_RESERVE,
AAVE,
STK_ABPT_V2_PROXY,
180_000 ether // TODO: what is the correct value here?
// 3. start emission on module v2
IAggregatedStakeToken(STK_ABPT_V2_PROXY).setDistributionEnd(
block.timestamp + GenericProposal.DISTRIBUTION_DURATION
);
DistributionTypes.AssetConfigInput[]
memory enableConfigs = new DistributionTypes.AssetConfigInput[](1);
enableConfigs[0] = DistributionTypes.AssetConfigInput({
emissionPerSecond: 6365740740740741, // same as current
emissionPerSecond: uint128(EMISSION_PER_SECOND),
totalStaked: 0, // it's overwritten internally
underlyingAsset: STK_ABPT_V2_PROXY
});
IAaveDistributionManager(STK_ABPT_V2_PROXY).configureAssets(enableConfigs);
MiscEthereum.AAVE_ECOSYSTEM_RESERVE_CONTROLLER.approve(
MiscEthereum.ECOSYSTEM_RESERVE,
AaveV3EthereumAssets.AAVE_UNDERLYING,
STK_ABPT_V2_PROXY,
EMISSION_PER_SECOND * GenericProposal.DISTRIBUTION_DURATION
);
}
}
Loading

0 comments on commit ce20220

Please sign in to comment.