Skip to content

Commit

Permalink
[NES-268] [N8] [Suggestion] Unable to remove componentToken (#118)
Browse files Browse the repository at this point in the history
* removecomponenttoken and update deployment scripts

* formatting

* aggregatetoken tests

* aggregate token tests

* formatting

* remove removecomponenttoken and ERC1967Proxy from deployment

* removecomponentttoken
  • Loading branch information
ungaro authored Dec 10, 2024
1 parent 0939b95 commit a78004d
Show file tree
Hide file tree
Showing 6 changed files with 368 additions and 12 deletions.
10 changes: 5 additions & 5 deletions nest/script/DeployNestContracts.s.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Script } from "forge-std/Script.sol";
import { Test } from "forge-std/Test.sol";
Expand All @@ -13,6 +12,8 @@ import { NestStaking } from "../src/NestStaking.sol";
import { IComponentToken } from "../src/interfaces/IComponentToken.sol";
import { AggregateTokenProxy } from "../src/proxy/AggregateTokenProxy.sol";
import { NestStakingProxy } from "../src/proxy/NestStakingProxy.sol";

import { pUSDProxy } from "../src/proxy/pUSDProxy.sol";
import { pUSD } from "../src/token/pUSD.sol";

// Concrete implementation of ComponentToken
Expand Down Expand Up @@ -43,7 +44,6 @@ contract DeployNestContracts is Script, Test {

function run() external {
vm.startBroadcast(NEST_ADMIN_ADDRESS);
ERC1967Proxy pUSDProxy = ERC1967Proxy(payable(PUSD_ADDRESS));

AggregateToken aggregateToken = new AggregateToken();
AggregateTokenProxy aggregateTokenProxy = new AggregateTokenProxy(
Expand All @@ -52,9 +52,9 @@ contract DeployNestContracts is Script, Test {
AggregateToken.initialize,
(
NEST_ADMIN_ADDRESS,
"Nest Insto Vault",
"NIV",
IComponentToken(address(pUSDProxy)),
"Nest RWA Vault",
"nRWA",
IComponentToken(PUSD_ADDRESS),
1e17, // ask price
1e17 // bid price
)
Expand Down
4 changes: 3 additions & 1 deletion nest/script/UpgradeNestContracts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import { AggregateTokenProxy } from "../src/proxy/AggregateTokenProxy.sol";
contract UpgradeNestContracts is Script, Test {

address private constant NEST_ADMIN_ADDRESS = 0xb015762405De8fD24d29A6e0799c12e0Ea81c1Ff;
address private constant BORING_VAULT_ADDRESS = 0xe644F07B1316f28a7F134998e021eA9f7135F351;

UUPSUpgradeable private constant AGGREGATE_TOKEN_PROXY =
UUPSUpgradeable(payable(0x659619AEdf381c3739B0375082C2d61eC1fD8835));

// Add the component token addresses
address private constant ASSET_TOKEN = 0xF66DFD0A9304D3D6ba76Ac578c31C84Dc0bd4A00;
address private constant ASSET_TOKEN = 0x2DEc3B6AdFCCC094C31a2DCc83a43b5042220Ea2;

// LiquidContinuousMultiTokenVault - Credbull
address private constant COMPONENT_TOKEN = 0x4B1fC984F324D2A0fDD5cD83925124b61175f5C6;
Expand Down
11 changes: 7 additions & 4 deletions nest/script/UpgradepUSD.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils
import { ERC1967Utils } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";

import { Script } from "forge-std/Script.sol";
import { Test } from "forge-std/Test.sol";
import { console2 } from "forge-std/console2.sol";

import { pUSDProxy } from "../src/proxy/pUSDProxy.sol";
import { pUSD } from "../src/token/pUSD.sol";

import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";

contract UpgradePUSD is Script, Test {
contract UpgradePUSD is Script {

// Constants
address private constant ADMIN_ADDRESS = 0xb015762405De8fD24d29A6e0799c12e0Ea81c1Ff;
Expand All @@ -35,6 +34,9 @@ contract UpgradePUSD is Script, Test {
uint256 public currentTotalSupply;
bool public isConnected;

// small hack to be excluded from coverage report
function test() public { }

function setUp() public {
// Try to read implementation slot from proxy, this only works with RPC
try vm.load(PUSD_PROXY, ERC1967Utils.IMPLEMENTATION_SLOT) returns (bytes32 implementation) {
Expand All @@ -56,12 +58,13 @@ contract UpgradePUSD is Script, Test {
console2.log("Vault:", currentVault);
console2.log("Total Supply:", currentTotalSupply);
} else {
vm.skip(true);
//TODO: Check this again
vm.skip(false);
isConnected = false;
}
} catch {
console2.log("No implementation found - skipping");
vm.skip(true);
vm.skip(false);
isConnected = false;
}
}
Expand Down
45 changes: 44 additions & 1 deletion nest/src/AggregateToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ pragma solidity ^0.8.25;
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import { ERC1155Holder } from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { StorageSlot } from "@openzeppelin/contracts/utils/StorageSlot.sol";

import { ComponentToken } from "./ComponentToken.sol";
import { IAggregateToken } from "./interfaces/IAggregateToken.sol";
Expand Down Expand Up @@ -55,6 +57,9 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
/// @notice Emitted when the AggregateToken contract is unpaused for deposits
event Unpaused();

/// @notice Emitted when the asset token is updated
event AssetTokenUpdated(IERC20 indexed oldAsset, IERC20 indexed newAsset);

// Errors

/**
Expand All @@ -63,6 +68,9 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
*/
error ComponentTokenAlreadyListed(IComponentToken componentToken);

/// @notice Emitted when a ComponentToken is removed from the component token list
event ComponentTokenRemoved(IComponentToken indexed componentToken);

/**
* @notice Indicates a failure because the ComponentToken is not in the component token list
* @param componentToken ComponentToken that is not in the component token list
Expand Down Expand Up @@ -124,7 +132,7 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
uint256 askPrice,
uint256 bidPrice
) public initializer {
super.initialize(owner, name, symbol, IERC20(address(asset_)), false, false);
super.initialize(owner, name, symbol, IERC20(address(asset_)), false, true);

AggregateTokenStorage storage $ = _getAggregateTokenStorage();
$.componentTokenList.push(asset_);
Expand Down Expand Up @@ -223,6 +231,41 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
emit ComponentTokenListed(componentToken);
}

/**
* @notice Remove a ComponentToken from the component token list
* @dev Only the owner can call this function. The ComponentToken must have zero balance to be removed.
* @param componentToken ComponentToken to remove
*/
function removeComponentToken(
IComponentToken componentToken
) external nonReentrant onlyRole(ADMIN_ROLE) {
AggregateTokenStorage storage $ = _getAggregateTokenStorage();

// Check if component token exists
if (!$.componentTokenMap[componentToken]) {
revert ComponentTokenNotListed(componentToken);
}

// Check if it's the current asset
if (address(componentToken) == asset()) {
revert ComponentTokenIsAsset(componentToken);
}

// Remove from mapping
$.componentTokenMap[componentToken] = false;

// Remove from array by finding and replacing with last element
for (uint256 i = 0; i < $.componentTokenList.length; i++) {
if ($.componentTokenList[i] == componentToken) {
$.componentTokenList[i] = $.componentTokenList[$.componentTokenList.length - 1];
$.componentTokenList.pop();
break;
}
}

emit ComponentTokenUnlisted(componentToken);
}

/**
* @notice Buy ComponentToken using `asset`
* @dev Only the owner can call this function, will revert if
Expand Down
1 change: 0 additions & 1 deletion nest/src/ComponentToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/
import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

Expand Down
Loading

0 comments on commit a78004d

Please sign in to comment.