Skip to content

Commit

Permalink
add ability to pause AggregateTokens (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
eyqs authored and ungaro committed Dec 12, 2024
1 parent cddb72f commit 8a65a37
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
65 changes: 64 additions & 1 deletion nest/src/AggregateToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
uint256 askPrice;
/// @dev Price at which users can sell the AggregateToken to receive `asset`, times the base
uint256 bidPrice;
/// @dev True if the AggregateToken contract is paused for deposits, false otherwise
bool paused;
}

// keccak256(abi.encode(uint256(keccak256("plume.storage.AggregateToken")) - 1)) & ~bytes32(uint256(0xff))
Expand All @@ -47,6 +49,14 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
/// @notice Role for the price updater of the AggregateToken
bytes32 public constant PRICE_UPDATER_ROLE = keccak256("PRICE_UPDATER_ROLE");

// Events

/// @notice Emitted when the AggregateToken contract is paused for deposits
event Paused();

/// @notice Emitted when the AggregateToken contract is unpaused for deposits
event Unpaused();

// Errors

/**
Expand Down Expand Up @@ -80,6 +90,15 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
*/
error InvalidAsset(IERC20 invalidAsset, IERC20 asset);

/// @notice Indicates a failure because the contract is paused for deposits
error DepositPaused();

/// @notice Indicates a failure because the contract is already paused for deposits
error AlreadyPaused();

/// @notice Indicates a failure because the contract is not paused for deposits
error NotPaused();

// Initializer

/**
Expand Down Expand Up @@ -114,6 +133,7 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
$.componentTokenMap[asset_] = true;
$.askPrice = askPrice;
$.bidPrice = bidPrice;
$.paused = false;
}

// Override Functions
Expand Down Expand Up @@ -143,6 +163,18 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
return super.asset();
}

/// @inheritdoc IComponentToken
function deposit(
uint256 assets,
address receiver,
address controller
) public override(ComponentToken, IComponentToken) returns (uint256 shares) {
if (_getAggregateTokenStorage().paused) {
revert DepositPaused();
}
return super.deposit(assets, receiver, controller);
}

/// @inheritdoc IComponentToken
function redeem(
uint256 shares,
Expand Down Expand Up @@ -248,7 +280,7 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
emit ComponentTokenSellRequested(msg.sender, componentToken, componentTokenAmount, requestId);
}

// Admin Setter Functions
// Admin Functions

/**
* @notice Set the price at which users can buy the AggregateToken using `asset`
Expand All @@ -272,6 +304,32 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
_getAggregateTokenStorage().bidPrice = bidPrice;
}

/**
* @notice Pause the AggregateToken contract for deposits
* @dev Only the owner can pause the AggregateToken contract for deposits
*/
function pause() external onlyRole(ADMIN_ROLE) {
AggregateTokenStorage storage $ = _getAggregateTokenStorage();
if ($.paused) {
revert AlreadyPaused();
}
$.paused = true;
emit Paused();
}

/**
* @notice Unpause the AggregateToken contract for deposits
* @dev Only the owner can unpause the AggregateToken contract for deposits
*/
function unpause() external onlyRole(ADMIN_ROLE) {
AggregateTokenStorage storage $ = _getAggregateTokenStorage();
if (!$.paused) {
revert NotPaused();
}
$.paused = false;
emit Unpaused();
}

// Getter View Functions

/// @notice Price at which users can buy the AggregateToken using `asset`, times the base
Expand All @@ -289,6 +347,11 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder {
return _getAggregateTokenStorage().componentTokenList;
}

/// @notice Returns true if the AggregateToken contract is paused for deposits
function isPaused() external view returns (bool) {
return _getAggregateTokenStorage().paused;
}

/**
* @notice Check if the given ComponentToken is in the component token list
* @param componentToken ComponentToken to check
Expand Down
4 changes: 3 additions & 1 deletion nest/src/ComponentToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ abstract contract ComponentToken is
/// @dev Reverts with Unimplemented() until convertToAssets is implemented by the concrete contract
/// @param owner Address to query the balance of
/// @return assets Total value held by the owner
function assetsOf(address owner) public view virtual returns (uint256 assets) {
function assetsOf(
address owner
) public view virtual returns (uint256 assets) {
return convertToAssets(balanceOf(owner));
}

Expand Down
4 changes: 3 additions & 1 deletion nest/src/interfaces/IComponentToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ interface IComponentToken {
* @param owner Address to query the balance of
* @return assets Total value held by the owner
*/
function assetsOf(address owner) external view returns (uint256 assets);
function assetsOf(
address owner
) external view returns (uint256 assets);

/**
* @notice Equivalent amount of shares for the given amount of assets
Expand Down

0 comments on commit 8a65a37

Please sign in to comment.