// SPDX-License-Identifier: Apache-2.0 // https://docs.soliditylang.org/en/v0.8.10/style-guide.html pragma solidity ^0.8.10; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import {ERC4626Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import {MathUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; import "src/interfaces/IMoolaLendingPool.sol"; import "src/interfaces/IStableToken.sol"; import "src/staking/StakedERC4626Upgradeable.sol"; import "src/interfaces/IRegistry.sol"; import "src/staking/SpiralsCUSDVault.sol"; import "src/vaults/ImpactVault.sol"; import "src/vaults/SpiralsCUSDImpactVault.sol"; import "src/staking/migration/IMigrationToImpactVault.sol"; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; contract SpiralsCUSDVaultMigration is IMigrationToImpactVault, SpiralsCUSDVault { /// @param _yields values will come from subgraph function transferAssetsToImpactVault( address[] memory _addrs, ImpactVault _vault, uint256[] memory _yields ) external onlyOwner whenPaused { for (uint256 i = 0; i < _addrs.length; i++) { transferAssetsToImpactVaultForAddress( _addrs[i], _vault, _yields[i] ); } } function transferAssetsToImpactVaultForAddress( address _address, ImpactVault _vault, uint256 _yield ) public onlyOwner whenPaused { uint256 cUSDStaked = balanceOf(_address); uint256 totalCUSD = cUSDStaked + _yield; if (totalCUSD == 0) { return; } // withdraw from Moola LP (mcUSD -> cUSD) c_moolaLendingPool.withdraw(asset(), totalCUSD, address(this)); _burn(_address, cUSDStaked); // deposit into new vault IERC20Upgradeable(asset()).approve(address(_vault), totalCUSD); SpiralsCUSDImpactVault cUSDVault = SpiralsCUSDImpactVault( payable(address(_vault)) ); cUSDVault.depositWithYield(cUSDStaked, _address, _yield); emit AssetsTransferredToImpactVault( _address, cUSDStaked, _yield, address(_vault) ); // This event will decrease cUSD staked count on Spirals subgraph // but as long as subgraph is handling "Deposit" event appropriately // on the new vault then we are good. emit Withdraw(msg.sender, _address, _address, cUSDStaked, cUSDStaked); } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }