-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add escrow migration spell * Archive deployed spell * Add escrow migration spell (#83) * Add escrow migration spell * Archive deployed spell
- Loading branch information
Showing
2 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
deployments/mainnet/spells/002_0xa3Ce97352C1469884EEF3547Ec9362329FE78Cf0.sol
This file contains 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,55 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity 0.8.26; | ||
|
||
import {IERC20} from "forge-std/interfaces/IERC20.sol"; | ||
|
||
interface RootLike { | ||
function relyContract(address, address) external; | ||
function executeScheduledRely(address) external; | ||
function delay() external view returns (uint64); | ||
} | ||
|
||
interface AuthLike { | ||
function rely(address) external; | ||
function deny(address) external; | ||
} | ||
|
||
interface OldEscrowLike { | ||
function approve(address token, address spender, uint256 value) external; | ||
} | ||
|
||
// Spell to migrate the escrow balances | ||
contract Spell { | ||
bool public done; | ||
string public constant description = "Liquidity Pool escrow migration spell"; | ||
|
||
address public constant LP_MULTISIG = 0xD9D30ab47c0f096b0AA67e9B8B1624504a63e7FD; | ||
address public constant OLD_DELAYED_ADMIN = 0x2559998026796Ca6fd057f3aa66F2d6ecdEd9028; | ||
address public constant OLD_ROOT = 0x498016d30Cd5f0db50d7ACE329C07313a0420502; | ||
address public constant OLD_ESCROW = 0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936; | ||
address public constant NEW_ESCROW = 0x0000000005F458Fd6ba9EEb5f365D83b7dA913dD; | ||
address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; | ||
|
||
function cast() public { | ||
require(!done, "spell-already-cast"); | ||
done = true; | ||
execute(); | ||
} | ||
|
||
function execute() internal { | ||
RootLike root = RootLike(OLD_ROOT); | ||
root.relyContract(OLD_ESCROW, address(this)); | ||
|
||
migrateBalance(USDC); | ||
|
||
AuthLike(OLD_ROOT).deny(address(this)); | ||
AuthLike(OLD_ESCROW).deny(address(this)); | ||
} | ||
|
||
function migrateBalance(address token) internal { | ||
OldEscrowLike escrow = OldEscrowLike(OLD_ESCROW); | ||
escrow.approve(token, address(this), type(uint256).max); | ||
IERC20(token).transferFrom(OLD_ESCROW, NEW_ESCROW, IERC20(token).balanceOf(OLD_ESCROW)); | ||
escrow.approve(token, address(this), 0); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
deployments/mainnet/spells/002_0xa3Ce97352C1469884EEF3547Ec9362329FE78Cf0.t.sol
This file contains 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,63 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity 0.8.26; | ||
|
||
import {ICentrifugeRouter} from "src/interfaces/ICentrifugeRouter.sol"; | ||
import "forge-std/Test.sol"; | ||
import "src/002.sol"; | ||
|
||
interface DelayedAdminLike { | ||
function scheduleRely(address spell) external; | ||
} | ||
|
||
contract SpellTest is Test { | ||
Spell spell; | ||
|
||
// Details related to pending redemption that is failing | ||
address investor1 = 0x32f5eF78AA9C7b8882D748331AdcFe0dfA4f1a14; | ||
address investor2 = 0xbe19e6AdF267248beE015dd3fbBa363E12ca8cE6; | ||
address vault = 0xa7607A638df0117E6718b93f8cFf53503A815D2f; | ||
ICentrifugeRouter router = ICentrifugeRouter(0x2F445BA946044C5F508a63eEaF7EAb673c69a1F4); | ||
|
||
IERC20 usdc; | ||
|
||
function setUp() public { | ||
spell = new Spell(); | ||
usdc = IERC20(spell.USDC()); | ||
} | ||
|
||
function testCastSuccessful() public { | ||
assertEq(usdc.balanceOf(spell.OLD_ESCROW()), 143360978110); | ||
assertEq(usdc.balanceOf(spell.NEW_ESCROW()), 0); | ||
|
||
vm.expectRevert(bytes("SafeTransferLib/safe-transfer-from-failed")); | ||
vm.prank(investor1); | ||
router.claimRedeem(vault, investor1, investor1); | ||
|
||
vm.expectRevert(bytes("SafeTransferLib/safe-transfer-from-failed")); | ||
vm.prank(investor2); | ||
router.claimRedeem(vault, investor2, investor2); | ||
|
||
castSpell(); | ||
|
||
assertEq(usdc.balanceOf(spell.OLD_ESCROW()), 0); | ||
assertEq(usdc.balanceOf(spell.NEW_ESCROW()), 143360978110); | ||
|
||
vm.prank(investor1); | ||
router.claimRedeem(vault, investor1, investor1); | ||
|
||
vm.prank(investor2); | ||
router.claimRedeem(vault, investor2, investor2); | ||
} | ||
|
||
function castSpell() internal { | ||
// Admin submits a tx to delayedAdmin in order to rely spell -> to be done manually before spell cast | ||
DelayedAdminLike delayedAdmin = DelayedAdminLike(spell.OLD_DELAYED_ADMIN()); | ||
vm.prank(spell.LP_MULTISIG()); | ||
delayedAdmin.scheduleRely(address(spell)); | ||
|
||
// Warp to the time when the spell can be cast -> current block + delay | ||
vm.warp(block.timestamp + RootLike(spell.OLD_ROOT()).delay()); | ||
RootLike(spell.OLD_ROOT()).executeScheduledRely(address(spell)); // --> to be called after delay has passed | ||
spell.cast(); | ||
} | ||
} |