@@ -7,7 +7,12 @@ import {IERC20} from "../misc/interfaces/IERC20.sol";
77import {Root} from "../admin/Root.sol " ;
88
99Root constant ROOT_V2 = Root (0x0C1fDfd6a1331a875EA013F3897fc8a76ada5DfC );
10- Root constant ROOT_V3 = Root (0x7Ed48C31f2fdC40d37407cBaBf0870B2b688368f );
10+
11+ address constant CONTRACT_UPDATER = 0x3B150B19245D2C366bc8f18c775b725DFB298F71 ;
12+ address constant FREEZE_ONLY_HOOK = 0xd5B243F05b2906F1f6C80c6096945faADa0731C1 ;
13+ address constant FULL_RESTRICTIONS_HOOK = 0x8E680873b4C77e6088b4Ba0aBD59d100c3D224a4 ;
14+ address constant FREELY_TRANSFERABLE_HOOK = 0x2a9B9C14851Baf7AD19f26607C9171CA1E7a1A61 ;
15+ address constant REDEMPTION_RESTRICTIONS_HOOK = 0xE5423eD8602Fa0F263e17b6212d88Efe42317f06 ;
1116
1217address constant CFG = 0xcccCCCcCCC33D538DBC2EE4fEab0a7A1FF4e8A94 ;
1318address constant WCFG = 0xc221b7E65FfC80DE234bbB6667aBDd46593D34F0 ;
@@ -51,46 +56,53 @@ contract V2CleaningsSpell {
5156 bool public done;
5257 string public constant description = "Pending cleanings from V2 " ;
5358
54- function cast () external {
59+ function cast (Root rootV3 ) external {
5560 require (! done, "Spell already executed " );
5661 done = true ;
5762
58- _updateCFGWards ();
59- _disableRootV2FromShareTokensV2 ();
63+ _updateCFGWards (rootV3 );
64+ _disableRootV2FromShareTokensV2 (rootV3 );
6065 _moveFundsFromEscrowToTreasury ();
61- _mintCFGToTreasury ();
66+ _relyContractUpdaterOnHooks (rootV3);
67+ _mintCFGToTreasury (rootV3);
6268
63- ROOT_V2.deny (address (this ));
64- ROOT_V3.deny (address (this ));
69+ if (address (ROOT_V2).code.length > 0 ) {
70+ ROOT_V2.deny (address (this ));
71+ }
72+ rootV3.deny (address (this ));
6573 }
6674
67- function _updateCFGWards () internal {
75+ function _updateCFGWards (Root rootV3 ) internal {
6876 // Check if CFG exists
6977 if (CFG.code.length > 0 ) {
7078 // Mainnet CFG only has the v2 root relied, need to replace with v3 root
7179 if (block .chainid == ETHEREUM_CHAIN_ID) {
72- ROOT_V2.relyContract (CFG, address (ROOT_V3));
73- ROOT_V2.relyContract (CFG, CFG_MINTER);
74- ROOT_V3.denyContract (CFG, IOU_CFG);
75- ROOT_V3.denyContract (CFG, address (ROOT_V2));
80+ if (address (ROOT_V2).code.length > 0 ) {
81+ ROOT_V2.relyContract (CFG, address (rootV3));
82+ ROOT_V2.relyContract (CFG, CFG_MINTER);
83+ rootV3.denyContract (CFG, address (ROOT_V2));
84+ }
85+ rootV3.denyContract (CFG, IOU_CFG);
7686 }
7787
7888 // Deny CREATE3 proxy on new chains
7989 if (block .chainid != ETHEREUM_CHAIN_ID) {
80- ROOT_V3 .denyContract (CFG, CREATE3_PROXY);
90+ rootV3 .denyContract (CFG, CREATE3_PROXY);
8191 }
8292 }
8393
8494 // Check if WCFG exists (only in Ethereum)
8595 if (WCFG.code.length > 0 ) {
86- Root (ROOT_V2).relyContract (WCFG, address (ROOT_V3));
87- ROOT_V3.denyContract (WCFG, WCFG_MULTISIG);
88- ROOT_V3.denyContract (WCFG, CHAINBRIDGE_ERC20_HANDLER);
89- ROOT_V3.denyContract (WCFG, address (ROOT_V2));
96+ if (address (ROOT_V2).code.length > 0 ) {
97+ Root (ROOT_V2).relyContract (WCFG, address (rootV3));
98+ rootV3.denyContract (WCFG, address (ROOT_V2));
99+ }
100+ rootV3.denyContract (WCFG, WCFG_MULTISIG);
101+ rootV3.denyContract (WCFG, CHAINBRIDGE_ERC20_HANDLER);
90102 }
91103 }
92104
93- function _disableRootV2FromShareTokensV2 () internal {
105+ function _disableRootV2FromShareTokensV2 (Root rootV3 ) internal {
94106 address [] memory shareTokens = new address [](2 );
95107 shareTokens[0 ] = TRANCHE_JTRSY;
96108 shareTokens[1 ] = TRANCHE_JAAA;
@@ -101,11 +113,11 @@ contract V2CleaningsSpell {
101113 // forgefmt: disable-next-item
102114 if (address (shareTokenV2).code.length > 0 &&
103115 shareTokenV2.wards (address (ROOT_V2)) == 1 &&
104- shareTokenV2.wards (address (ROOT_V3 )) == 1
116+ shareTokenV2.wards (address (rootV3 )) == 1
105117 ) {
106- ROOT_V3 .relyContract (address (shareTokenV2), address (this ));
118+ rootV3 .relyContract (address (shareTokenV2), address (this ));
107119 shareTokenV2.deny (address (ROOT_V2));
108- ROOT_V3 .denyContract (address (shareTokenV2), address (this ));
120+ rootV3 .denyContract (address (shareTokenV2), address (this ));
109121 }
110122 }
111123 }
@@ -119,6 +131,8 @@ contract V2CleaningsSpell {
119131 usdc = USDC_BASE;
120132 } else if (block .chainid == ARBITRUM_CHAIN_ID) {
121133 usdc = USDC_ARBITRUM;
134+ } else {
135+ return ;
122136 }
123137
124138 ROOT_V2.relyContract (address (ESCROW_V2), address (this ));
@@ -130,14 +144,21 @@ contract V2CleaningsSpell {
130144 }
131145 }
132146
133- function _mintCFGToTreasury () internal {
147+ function _relyContractUpdaterOnHooks (Root rootV3 ) internal {
148+ rootV3.relyContract (FREEZE_ONLY_HOOK, CONTRACT_UPDATER);
149+ rootV3.relyContract (FULL_RESTRICTIONS_HOOK, CONTRACT_UPDATER);
150+ rootV3.relyContract (FREELY_TRANSFERABLE_HOOK, CONTRACT_UPDATER);
151+ rootV3.relyContract (REDEMPTION_RESTRICTIONS_HOOK, CONTRACT_UPDATER);
152+ }
153+
154+ function _mintCFGToTreasury (Root rootV3 ) internal {
134155 if (block .chainid == ETHEREUM_CHAIN_ID) {
135156 // Subtract wCFG balance held by the IOU_CFG contract, since those were already
136157 // redeemed 1:1 for CFG and the wCFG total supply was not reduced upon redemption.
137158 uint256 amount = IERC20 (WCFG).totalSupply () - IERC20 (WCFG).balanceOf (IOU_CFG) + CENTRIFUGE_CHAIN_CFG_AMOUNT;
138- ROOT_V3 .relyContract (CFG, address (this ));
159+ rootV3 .relyContract (CFG, address (this ));
139160 CFGTokenLike (CFG).mint (CNF_TREASURY_WALLET, amount);
140- ROOT_V3 .denyContract (CFG, address (this ));
161+ rootV3 .denyContract (CFG, address (this ));
141162 }
142163 }
143164}
0 commit comments