Skip to content
Open
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
25 changes: 25 additions & 0 deletions src/spell/V2CleaningsSpell.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,23 @@ IERC20 constant USDC_ETHEREUM = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB4
IERC20 constant USDC_BASE = IERC20(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);
IERC20 constant USDC_ARBITRUM = IERC20(0xaf88d065e77c8cC2239327C5EDb3A432268e5831);

address constant CNF_TREASURY_WALLET = 0xD052A46b8e0C89fAcB393805E1917AfD20f293Cb;
Copy link
Contributor

Choose a reason for hiding this comment

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

Verified ✅


// Centrifuge Chain CFG amount derivation:
// Total issuance on Centrifuge Chain: 578_423_119_298_517_443_782_165_480
// Minus migrated CFG (4dpEcgqFp38bzzT5VruKgbfVs6zcDMFRKUetx3fz2ndLRHMu): -350_860_057_533_953_490_820_324_585
// Minus chainbridge (4dpEcgqFp8UL6eA3b7hhtdj7qftHRZE7g1uadHyuw1WSNSgH): -192_726_451_002_520_311_526_501_638
// = Remaining CFG on Centrifuge Chain: 34_836_610_762_043_641_435_339_257
uint256 constant CENTRIFUGE_CHAIN_CFG_AMOUNT = 34_836_610_762_043_641_435_339_257;

uint256 constant ETHEREUM_CHAIN_ID = 1;
uint256 constant BASE_CHAIN_ID = 8453;
uint256 constant ARBITRUM_CHAIN_ID = 42161;

interface CFGTokenLike {
function mint(address to, uint256 value) external;
}

interface EscrowV2Like is IAuth {
function approveMax(address token, address spender) external;
}
Expand All @@ -51,6 +64,7 @@ contract V2CleaningsSpell {
_disableRootV2FromShareTokensV2(rootV3);
_moveFundsFromEscrowToTreasury();
_relyContractUpdaterOnHooks(rootV3);
_mintCFGToTreasury(rootV3);

if (address(ROOT_V2).code.length > 0) {
ROOT_V2.deny(address(this));
Expand Down Expand Up @@ -136,4 +150,15 @@ contract V2CleaningsSpell {
rootV3.relyContract(FREELY_TRANSFERABLE_HOOK, CONTRACT_UPDATER);
rootV3.relyContract(REDEMPTION_RESTRICTIONS_HOOK, CONTRACT_UPDATER);
}

function _mintCFGToTreasury(Root rootV3) internal {
if (block.chainid == ETHEREUM_CHAIN_ID) {
// Subtract wCFG balance held by the IOU_CFG contract, since those were already
// redeemed 1:1 for CFG and the wCFG total supply was not reduced upon redemption.
uint256 amount = IERC20(WCFG).totalSupply() - IERC20(WCFG).balanceOf(IOU_CFG) + CENTRIFUGE_CHAIN_CFG_AMOUNT;
rootV3.relyContract(CFG, address(this));
CFGTokenLike(CFG).mint(CNF_TREASURY_WALLET, amount);
rootV3.denyContract(CFG, address(this));
}
Comment on lines +155 to +162
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the WCFG contract already denyed to mint new CFG tokens?

}
}
22 changes: 21 additions & 1 deletion test/integration/spell/V2Cleanings.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ import {
ESCROW_V2,
USDC_ETHEREUM,
USDC_BASE,
USDC_ARBITRUM
USDC_ARBITRUM,
CNF_TREASURY_WALLET,
CENTRIFUGE_CHAIN_CFG_AMOUNT
} from "../../../src/spell/V2CleaningsSpell.sol";

contract V2CleaningsSpellTest is Test {
Expand All @@ -42,6 +44,8 @@ contract V2CleaningsSpellTest is Test {
address constant GUARDIAN_V2_BASE = 0x427A1ce127b1775e4Cbd4F58ad468B9F832eA7e9;
address constant ROOT_V3_ETH = 0x7Ed48C31f2fdC40d37407cBaBf0870B2b688368f;

uint256 constant MAX_POST_MINT_CFG_SUPPLY = 692_049_712_426_095_885_688_933_007;
Copy link
Contributor Author

Choose a reason for hiding this comment

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


function _testCase(string memory network, string memory rpcUrl) public {
vm.createSelectFork(rpcUrl);

Expand All @@ -58,6 +62,15 @@ contract V2CleaningsSpellTest is Test {

// ----- PRE SPELL -----

uint256 preCfgTotalSupply;
uint256 preCfgMintTreasuryBalance;
if (CFG.code.length > 0) {
preCfgTotalSupply = IERC20(CFG).totalSupply();
preCfgMintTreasuryBalance = IERC20(CFG).balanceOf(CNF_TREASURY_WALLET);
}
uint256 preWcfgTotalSupply = block.chainid == ETHEREUM_CHAIN_ID ? IERC20(WCFG).totalSupply() : 0;
uint256 preWcfgBalanceOfIouCfg = block.chainid == ETHEREUM_CHAIN_ID ? IERC20(WCFG).balanceOf(IOU_CFG) : 0;

IERC20 usdc = _usdc();
uint256 preTreasuryValue;
uint256 preEscrowValue;
Expand Down Expand Up @@ -100,6 +113,13 @@ contract V2CleaningsSpellTest is Test {

assertEq(IAuth(CFG).wards(address(ROOT_V2)), 0);
assertEq(IAuth(CFG).wards(IOU_CFG), 0);

// CFG minting assertions
uint256 expectedMintAmount = preWcfgTotalSupply - preWcfgBalanceOfIouCfg + CENTRIFUGE_CHAIN_CFG_AMOUNT;
assertEq(IERC20(CFG).totalSupply(), preCfgTotalSupply + expectedMintAmount);
assertEq(IERC20(CFG).totalSupply(), MAX_POST_MINT_CFG_SUPPLY, "Total CFG supply exceeds max post-mint cap");
assertEq(IERC20(CFG).balanceOf(CNF_TREASURY_WALLET), preCfgMintTreasuryBalance + expectedMintAmount);
assertEq(IAuth(CFG).wards(address(spell)), 0);
}

if (TRANCHE_JTRSY.code.length > 0) {
Expand Down
Loading