-
Notifications
You must be signed in to change notification settings - Fork 15
Migration spell #385
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
Open
ilinzweilin
wants to merge
25
commits into
main
Choose a base branch
from
migration-spell
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Migration spell #385
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
17dd13c
add simulation for tranche token migration
ilinzweilin 8dfcbf2
add comments
ilinzweilin b88e336
Merge remote-tracking branch 'origin' into tranche-token-migration-fo…
ilinzweilin 5f15f10
Merge branch 'main' into tranche-token-migration-fork-test
ilinzweilin a23c86c
add migration spell
ilinzweilin ac67490
add migration spell
ilinzweilin c88ff07
Merge branch 'main' into migration-spell
AStox f0e4945
migrate all members to new memberlist and claim any unclaimed tokens
AStox 1c2bbbb
Add denies
AStox b809f8b
fix build
AStox 1922321
update fork test
AStox 77f62b1
upgrade fork test, fix a missing rely and use maxMint instead of escr…
AStox 0f8e790
wip: add test for fork testing against a real deployment
AStox 2bb0914
Add base addresses
AStox e6c00e3
update tests and spells construction
AStox 1e310d3
forge fmt
AStox c63127a
Merge branch 'main' into migration-spell
AStox 5548e5b
derive some addresses via the old vault
AStox 05498a2
add new deployments
AStox 3b202f3
derive currency id, update token names, use approximate asserts
AStox b283ca5
update NS3SR old share metadata
AStox b359596
break spell into two executable parts
AStox c127965
update tests to cast both parts seperately
AStox e030960
update tests to test all spells at once
AStox 6d5636c
get the allEVMSpells test working
AStox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| // SPDX-License-Identifier: AGPL-3.0-only | ||
| pragma solidity 0.8.26; | ||
|
|
||
| import {IRoot} from "src/interfaces/IRoot.sol"; | ||
| import {IPoolManager} from "src/interfaces/IPoolManager.sol"; | ||
| import {RestrictionUpdate} from "src/interfaces/token/IRestrictionManager.sol"; | ||
| import {ITranche} from "src/interfaces/token/ITranche.sol"; | ||
| import {InvestmentManager} from "src/InvestmentManager.sol"; | ||
| import {CastLib} from "src/libraries/CastLib.sol"; | ||
| import {IAuth} from "src/interfaces/IAuth.sol"; | ||
|
|
||
| interface IPoolManagerNew is IPoolManager { | ||
| function isPoolActive(uint64 poolId) external view returns (bool); | ||
| } | ||
|
|
||
| interface ITrancheOld { | ||
| function authTransferFrom(address from, address to, uint256 value) external returns (bool); | ||
| } | ||
|
|
||
| interface IVaultOld { | ||
| function poolId() external view returns (uint64); | ||
| function trancheId() external view returns (bytes16); | ||
| function share() external view returns (address); | ||
| function manager() external view returns (address); | ||
| function escrow() external view returns (address); | ||
| function asset() external view returns (address); | ||
| } | ||
|
|
||
| interface IPoolManagerOld { | ||
| function currencyAddressToId(address currency) external view returns (uint128); | ||
| } | ||
|
|
||
| contract MigrationSpellBase { | ||
| using CastLib for *; | ||
|
|
||
| string public NETWORK; | ||
| address public ROOT_NEW; | ||
| IRoot public rootNew; | ||
| address public GUARDIAN_NEW; | ||
| address public POOLMANAGER_NEW; | ||
| address public RESTRICTIONMANAGER_NEW; | ||
| ITranche public trancheTokenNew; | ||
| IPoolManagerNew poolManager; | ||
|
|
||
| address public ROOT_OLD; | ||
| IRoot public rootOld; | ||
| address public ADMIN_MULTISIG; | ||
| address public GUARDIAN_OLD; | ||
| address public VAULT_OLD; | ||
| uint64 POOL_ID; | ||
| bytes16 TRANCHE_ID; | ||
| uint8 DECIMALS; | ||
| uint128 CURRENCY_ID; | ||
| IVaultOld public vaultOld; | ||
| ITranche trancheTokenOld; | ||
| InvestmentManager investmentManagerOld; | ||
| IPoolManagerOld poolManagerOld; | ||
|
|
||
| string public NAME; | ||
| string public SYMBOL; | ||
| string public NAME_OLD; | ||
| string public SYMBOL_OLD; | ||
| address[] public memberlistMembers; | ||
| mapping(address => uint64) public validUntil; | ||
| bool public partOneDone; | ||
| bool public partTwoDone; | ||
| uint256 constant ONE = 10 ** 27; | ||
| address self; | ||
|
|
||
| function castPartOne() public { | ||
| require(!partOneDone, "spell-already-cast"); | ||
| partOneDone = true; | ||
| executePartOne(); | ||
| } | ||
|
|
||
| function castPartTwo() public { | ||
| require(partOneDone, "part-one-not-cast"); | ||
| require(!partTwoDone, "spell-already-cast"); | ||
| partTwoDone = true; | ||
| executePartTwo(); | ||
| } | ||
|
|
||
| function executePartOne() internal { | ||
| self = address(this); | ||
| rootOld = IRoot(address(ROOT_OLD)); | ||
| rootNew = IRoot(address(ROOT_NEW)); | ||
| vaultOld = IVaultOld(VAULT_OLD); | ||
| POOL_ID = vaultOld.poolId(); | ||
| TRANCHE_ID = vaultOld.trancheId(); | ||
| poolManager = IPoolManagerNew(address(POOLMANAGER_NEW)); | ||
| trancheTokenOld = ITranche(vaultOld.share()); | ||
| DECIMALS = trancheTokenOld.decimals(); | ||
| investmentManagerOld = InvestmentManager(vaultOld.manager()); | ||
| poolManagerOld = IPoolManagerOld(address(investmentManagerOld.poolManager())); | ||
| CURRENCY_ID = poolManagerOld.currencyAddressToId(vaultOld.asset()); | ||
| rootOld.relyContract(address(investmentManagerOld), self); | ||
| rootOld.relyContract(address(trancheTokenOld), self); | ||
|
|
||
| // deploy new tranche token | ||
| rootNew.relyContract(address(POOLMANAGER_NEW), self); | ||
| if (!poolManager.isPoolActive(POOL_ID)) { | ||
| poolManager.addPool(POOL_ID); | ||
| } | ||
| poolManager.addTranche(POOL_ID, TRANCHE_ID, NAME, SYMBOL, DECIMALS, RESTRICTIONMANAGER_NEW); | ||
| if (poolManager.assetToId(vaultOld.asset()) == 0) { | ||
| poolManager.addAsset(CURRENCY_ID, vaultOld.asset()); | ||
| } | ||
| poolManager.allowAsset(POOL_ID, CURRENCY_ID); | ||
| trancheTokenNew = ITranche(poolManager.deployTranche(POOL_ID, TRANCHE_ID)); | ||
| rootNew.relyContract(address(trancheTokenNew), self); | ||
| poolManager.deployVault(POOL_ID, TRANCHE_ID, vaultOld.asset()); | ||
| } | ||
|
|
||
| function executePartTwo() internal { | ||
| // add all old members to new memberlist and claim any tokens | ||
| uint256 holderBalance; | ||
| for (uint8 i; i < memberlistMembers.length; i++) { | ||
| // add member to new memberlist | ||
| poolManager.updateRestriction( | ||
| POOL_ID, | ||
| TRANCHE_ID, | ||
| abi.encodePacked( | ||
| uint8(RestrictionUpdate.UpdateMember), | ||
| address(memberlistMembers[i]).toBytes32(), | ||
| validUntil[memberlistMembers[i]] | ||
| ) | ||
| ); | ||
| if (memberlistMembers[i] != vaultOld.escrow()) { | ||
| uint256 maxMint = investmentManagerOld.maxMint(VAULT_OLD, memberlistMembers[i]); | ||
| if (maxMint > 0) { | ||
| // Claim any unclaimed tokens the user may have | ||
| investmentManagerOld.mint(VAULT_OLD, maxMint, memberlistMembers[i], memberlistMembers[i]); | ||
| } | ||
| holderBalance = trancheTokenOld.balanceOf(memberlistMembers[i]); | ||
| if (holderBalance > 0) { | ||
| // mint new token to the holder's wallet | ||
| trancheTokenNew.mint(memberlistMembers[i], holderBalance); | ||
| // transfer old tokens from holders' wallets | ||
| ITrancheOld(vaultOld.share()).authTransferFrom(memberlistMembers[i], self, holderBalance); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // burn entire supply of old tranche tokens | ||
| trancheTokenOld.burn(self, trancheTokenOld.balanceOf(self)); | ||
|
|
||
| // rename old tranche token | ||
| trancheTokenOld.file("name", NAME_OLD); | ||
| trancheTokenOld.file("symbol", SYMBOL_OLD); | ||
|
|
||
| // denies | ||
| rootNew.denyContract(address(POOLMANAGER_NEW), self); | ||
| rootNew.denyContract(address(trancheTokenNew), self); | ||
| rootOld.denyContract(address(trancheTokenOld), self); | ||
| rootOld.denyContract(address(investmentManagerOld), self); | ||
| IAuth(address(rootOld)).deny(self); | ||
| IAuth(address(rootNew)).deny(self); | ||
| } | ||
|
|
||
| function getNumberOfMigratedMembers() public view returns (uint256) { | ||
| return memberlistMembers.length; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| pragma solidity 0.8.26; | ||
|
|
||
| import {IRoot} from "src/interfaces/IRoot.sol"; | ||
| import {IPoolManager} from "src/interfaces/IPoolManager.sol"; | ||
| import {RestrictionUpdate} from "src/interfaces/token/IRestrictionManager.sol"; | ||
| import {ITranche} from "src/interfaces/token/ITranche.sol"; | ||
| import {IInvestmentManager} from "src/interfaces/IInvestmentManager.sol"; | ||
| import {IAuth} from "src/interfaces/IAuth.sol"; | ||
| import {MigrationSpellBase} from "src/spell/MigrationSpellBase.sol"; | ||
|
|
||
| interface ITrancheOld { | ||
| function authTransferFrom(address from, address to, uint256 value) external returns (bool); | ||
| } | ||
|
|
||
| // spell to migrate tranche tokens | ||
| contract MigrationSpell is MigrationSpellBase { | ||
| constructor() { | ||
| NETWORK = "ethereum-mainnet"; | ||
| // old deployment addresses | ||
| ROOT_OLD = 0x498016d30Cd5f0db50d7ACE329C07313a0420502; | ||
| ADMIN_MULTISIG = 0xD9D30ab47c0f096b0AA67e9B8B1624504a63e7FD; | ||
| GUARDIAN_OLD = 0x2559998026796Ca6fd057f3aa66F2d6ecdEd9028; | ||
|
|
||
| // old pool addresses | ||
| VAULT_OLD = 0x110379504D933BeD2E485E281bc3909D1E7C9E5D; | ||
|
|
||
| // new deployment addresses | ||
| ROOT_NEW = 0x0C1fDfd6a1331a875EA013F3897fc8a76ada5DfC; | ||
| GUARDIAN_NEW = 0x09ab10a9c3E6Eac1d18270a2322B6113F4C7f5E8; | ||
| POOLMANAGER_NEW = 0x91808B5E2F6d7483D41A681034D7c9DbB64B9E29; | ||
| RESTRICTIONMANAGER_NEW = 0x4737C3f62Cc265e786b280153fC666cEA2fBc0c0; | ||
|
|
||
| // information to deploy the new tranche token & liquidity pool to be able to migrate the tokens | ||
| NAME = "Anemoy DeFi Yield Fund 1"; | ||
| SYMBOL = "DYF"; | ||
| NAME_OLD = "DYF (deprecated)"; | ||
| SYMBOL_OLD = "DYF-DEPRECATED"; | ||
|
|
||
| memberlistMembers = [0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936, 0x30d3bbAE8623d0e9C0db5c27B82dCDA39De40997]; | ||
| validUntil[0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936] = type(uint64).max; | ||
| validUntil[0x30d3bbAE8623d0e9C0db5c27B82dCDA39De40997] = 2032178598; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| pragma solidity 0.8.26; | ||
|
|
||
| import {MigrationSpellBase} from "src/spell/MigrationSpellBase.sol"; | ||
|
|
||
| interface ITrancheOld { | ||
| function authTransferFrom(address from, address to, uint256 value) external returns (bool); | ||
| } | ||
|
|
||
| contract MigrationSpell is MigrationSpellBase { | ||
| constructor() { | ||
| NETWORK = "base-mainnet"; | ||
| // old deployment addresses | ||
| ROOT_OLD = 0x498016d30Cd5f0db50d7ACE329C07313a0420502; | ||
| ADMIN_MULTISIG = 0x8b83962fB9dB346a20c95D98d4E312f17f4C0d9b; | ||
| GUARDIAN_OLD = 0x2559998026796Ca6fd057f3aa66F2d6ecdEd9028; | ||
|
|
||
| // old pool addresses | ||
| VAULT_OLD = 0xa0872E8D2975483b2Ab4Afcee729133D8666F6f5; | ||
|
|
||
| // new deployment addresses | ||
| ROOT_NEW = 0x0C1fDfd6a1331a875EA013F3897fc8a76ada5DfC; | ||
| GUARDIAN_NEW = 0x427A1ce127b1775e4Cbd4F58ad468B9F832eA7e9; | ||
| POOLMANAGER_NEW = 0x7f192F34499DdB2bE06c4754CFf2a21c4B056994; | ||
| RESTRICTIONMANAGER_NEW = 0x4737C3f62Cc265e786b280153fC666cEA2fBc0c0; | ||
|
|
||
| // information to deploy the new tranche token & liquidity pool to be able to migrate the tokens | ||
| NAME = "Anemoy Liquid Treasury Fund 1"; | ||
| SYMBOL = "LTF"; | ||
|
|
||
| NAME_OLD = "LTF (deprecated)"; | ||
| SYMBOL_OLD = "LTF-DEPRECATED"; | ||
|
|
||
| memberlistMembers = [ | ||
| 0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936, | ||
| 0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb, | ||
| 0x86552B8d4F4a600D92d516eE8eA8B922EFEcB561 | ||
| ]; | ||
|
|
||
| validUntil[0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936] = type(uint64).max; | ||
| validUntil[0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb] = 2035284942; | ||
| validUntil[0x86552B8d4F4a600D92d516eE8eA8B922EFEcB561] = 2037188297; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| pragma solidity 0.8.26; | ||
|
|
||
| import {MigrationSpellBase} from "src/spell/MigrationSpellBase.sol"; | ||
|
|
||
| interface ITrancheOld { | ||
| function authTransferFrom(address from, address to, uint256 value) external returns (bool); | ||
| } | ||
|
|
||
| contract MigrationSpell is MigrationSpellBase { | ||
| constructor() { | ||
| NETWORK = "celo-mainnet"; | ||
| // old deployment addresses | ||
| ROOT_OLD = 0x498016d30Cd5f0db50d7ACE329C07313a0420502; | ||
| ADMIN_MULTISIG = 0x2464f95F6901233bF4a0130A3611d5B4CBd83195; | ||
| GUARDIAN_OLD = 0x2559998026796Ca6fd057f3aa66F2d6ecdEd9028; | ||
|
|
||
| // old pool addresses | ||
| VAULT_OLD = 0xa0872E8D2975483b2Ab4Afcee729133D8666F6f5; | ||
|
|
||
| // new deployment addresses | ||
| ROOT_NEW = 0x89e0E9ef81966BfA7D64BBE76394D36014a685c3; | ||
| GUARDIAN_NEW = 0x32043A41F4be198C4f6590312F7A7b91624Cab57; | ||
| POOLMANAGER_NEW = 0xa3Ce97352C1469884EEF3547Ec9362329FE78Cf0; | ||
| RESTRICTIONMANAGER_NEW = 0x9d5fbC48077863d63a883f44F66aCCde72A9D4e2; | ||
|
|
||
| // information to deploy the new tranche token & liquidity pool to be able to migrate the tokens | ||
| NAME = "Anemoy Liquid Treasury Fund 1"; | ||
| SYMBOL = "LTF"; | ||
|
|
||
| NAME_OLD = "LTF (deprecated)"; | ||
| SYMBOL_OLD = "LTF-DEPRECATED"; | ||
|
|
||
| memberlistMembers = [ | ||
| 0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936, | ||
| 0x0D9E269ECc319BAE886Dd8c8B98F7B89269C2B1B, | ||
| 0x6854f6671c1934c77cf7592B0b264f762614014E | ||
| ]; | ||
|
|
||
| validUntil[0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936] = type(uint64).max; | ||
| validUntil[0x0D9E269ECc319BAE886Dd8c8B98F7B89269C2B1B] = 2020186137; | ||
| validUntil[0x6854f6671c1934c77cf7592B0b264f762614014E] = 2020262249; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| pragma solidity 0.8.26; | ||
|
|
||
| import {MigrationSpellBase} from "src/spell/MigrationSpellBase.sol"; | ||
|
|
||
| // spell to migrate tranche tokens | ||
| contract MigrationSpell is MigrationSpellBase { | ||
| constructor() { | ||
| NETWORK = "ethereum-mainnet"; | ||
| // old deployment addresses | ||
| ROOT_OLD = 0x498016d30Cd5f0db50d7ACE329C07313a0420502; | ||
| ADMIN_MULTISIG = 0xD9D30ab47c0f096b0AA67e9B8B1624504a63e7FD; | ||
| GUARDIAN_OLD = 0x2559998026796Ca6fd057f3aa66F2d6ecdEd9028; | ||
|
|
||
| // old pool addresses | ||
| VAULT_OLD = 0xB3AC09cd5201569a821d87446A4aF1b202B10aFd; | ||
|
|
||
| // new deployment addresses | ||
| ROOT_NEW = 0x0C1fDfd6a1331a875EA013F3897fc8a76ada5DfC; | ||
| GUARDIAN_NEW = 0x09ab10a9c3E6Eac1d18270a2322B6113F4C7f5E8; | ||
| POOLMANAGER_NEW = 0x91808B5E2F6d7483D41A681034D7c9DbB64B9E29; | ||
| RESTRICTIONMANAGER_NEW = 0x4737C3f62Cc265e786b280153fC666cEA2fBc0c0; | ||
|
|
||
| // information to deploy the new tranche token & liquidity pool to be able to migrate the tokens | ||
| NAME = "Anemoy Liquid Treasury Fund 1"; | ||
| SYMBOL = "LTF"; | ||
|
|
||
| NAME_OLD = "LTF (deprecated)"; | ||
| SYMBOL_OLD = "LTF-DEPRECATED"; | ||
|
|
||
| memberlistMembers = [ | ||
| 0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936, | ||
| 0xeF08Bb6F5F9494faf2316402802e54089E6322eb, | ||
| 0x30d3bbAE8623d0e9C0db5c27B82dCDA39De40997, | ||
| 0xeEDC395aAAb05e5fb6130A8C5AEbAE48E7739B78, | ||
| 0x2923c1B5313F7375fdaeE80b7745106deBC1b53E, | ||
| 0x14FFe68D005e58f08c27dC0c999f75639682276c, | ||
| 0x86552B8d4F4a600D92d516eE8eA8B922EFEcB561 | ||
| ]; | ||
|
|
||
| validUntil[0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936] = type(uint64).max; | ||
| validUntil[0xeF08Bb6F5F9494faf2316402802e54089E6322eb] = 2017150288; | ||
| validUntil[0x30d3bbAE8623d0e9C0db5c27B82dCDA39De40997] = 2017323212; | ||
| validUntil[0xeEDC395aAAb05e5fb6130A8C5AEbAE48E7739B78] = 3745713365; | ||
| validUntil[0x2923c1B5313F7375fdaeE80b7745106deBC1b53E] = 2031229099; | ||
| validUntil[0x14FFe68D005e58f08c27dC0c999f75639682276c] = 2035299660; | ||
| validUntil[0x86552B8d4F4a600D92d516eE8eA8B922EFEcB561] = 2037188261; | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.