Skip to content

Commit 8fff1a6

Browse files
committed
Add EmergencyPause functionality and related events to IAssetManager and IAssetManagerEvents interfaces. Introduce consolidateSmallTickets method for managing small redemption tickets. Update AssetManagerSettings and CollateralType to reflect changes in token invalidation handling.
1 parent 6dfa371 commit 8fff1a6

21 files changed

+246
-172
lines changed

coston/IAssetManager.sol

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {AvailableAgentInfo} from "./data/AvailableAgentInfo.sol";
1212
import {RedemptionTicketInfo} from "./data/RedemptionTicketInfo.sol";
1313
import {RedemptionRequestInfo} from "./data/RedemptionRequestInfo.sol";
1414
import {CollateralReservationInfo} from "./data/CollateralReservationInfo.sol";
15+
import {EmergencyPause} from "./data/EmergencyPause.sol";
1516
import {IAssetManagerEvents} from "./IAssetManagerEvents.sol";
1617
import {IAgentPing} from "./IAgentPing.sol";
1718
import {IRedemptionTimeExtension} from "./IRedemptionTimeExtension.sol";
@@ -96,22 +97,18 @@ interface IAssetManager is
9697
function emergencyPaused() external view returns (bool);
9798

9899
/**
99-
* The time when emergency pause mode will end automatically.
100-
*/
101-
function emergencyPausedUntil() external view returns (uint256);
102-
103-
////////////////////////////////////////////////////////////////////////////////////
104-
// Emergency pause transfers
105-
106-
/**
107-
* If true, the system is in emergency pause mode and most operations (mint, redeem, liquidate) are disabled.
100+
* Emergency pause level defines which operations are paused:
101+
* NONE - pause is not active,
102+
* START_OPERATIONS - prevent starting mint, redeem, liquidation (start/liquidate) and core vault transfer/return,
103+
* FULL - everything from START_OPERATIONS, plus prevent finishing or defulating already started mints and redeems,
104+
* FULL_AND_TRANSFER - everything from FULL, plus prevent FAsset transfers.
108105
*/
109-
function transfersEmergencyPaused() external view returns (bool);
106+
function emergencyPauseLevel() external view returns (EmergencyPause.Level);
110107

111108
/**
112109
* The time when emergency pause mode will end automatically.
113110
*/
114-
function transfersEmergencyPausedUntil() external view returns (uint256);
111+
function emergencyPausedUntil() external view returns (uint256);
115112

116113
////////////////////////////////////////////////////////////////////////////////////
117114
// Asset manager upgrading state
@@ -264,13 +261,6 @@ interface IAssetManager is
264261
string memory _name
265262
) external;
266263

267-
/**
268-
* If the current agent's vault collateral token gets deprecated, the agent must switch with this method.
269-
* NOTE: may only be called by the agent vault owner.
270-
* NOTE: at the time of switch, the agent must have enough of both collaterals in the vault.
271-
*/
272-
function switchVaultCollateral(address _agentVault, IERC20 _token) external;
273-
274264
/**
275265
* When current pool collateral token contract (WNat) is replaced by the method setPoolWNatCollateralType,
276266
* pools don't switch automatically. Instead, the agent must call this method that swaps old WNat tokens for
@@ -808,7 +798,7 @@ interface IAssetManager is
808798
);
809799

810800
////////////////////////////////////////////////////////////////////////////////////
811-
// Dust
801+
// Dust and small ticket management
812802

813803
/**
814804
* Due to the minting pool fees or after a lot size change by the governance,
@@ -824,6 +814,20 @@ interface IAssetManager is
824814
*/
825815
function convertDustToTicket(address _agentVault) external;
826816

817+
/**
818+
* If lot size is increased, there may be many tickets less than one lot in the queue.
819+
* In extreme cases, this could prevent redemptions, if there weren't any tickets above 1 lot
820+
* among the first `maxRedeemedTickets` tickets.
821+
* To fix this, call this method. It converts small tickets to dust and when the dust exceeds one lot
822+
* adds it to the ticket.
823+
* Since the method just cleans the redemption queue it can be called by anybody.
824+
* @param _firstTicketId if nonzero, the ticket id of starting ticket; if zero, the starting ticket will
825+
* be the redemption queue's first ticket id.
826+
* When the method finishes, it emits RedemptionTicketsConsolidated event with the nextTicketId
827+
* parameter. If it is nonzero, the method should be invoked again with this value as _firstTicketId.
828+
*/
829+
function consolidateSmallTickets(uint256 _firstTicketId) external;
830+
827831
////////////////////////////////////////////////////////////////////////////////////
828832
// Liquidation
829833

coston/IAssetManagerEvents.sol

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >=0.7.6 <0.9;
33

4+
import {EmergencyPause} from "./data/EmergencyPause.sol";
5+
46
/**
57
* All asset manager events.
68
*/
@@ -337,6 +339,16 @@ interface IAssetManagerEvents {
337339
uint256 indexed redemptionTicketId
338340
);
339341

342+
/**
343+
* Method `consolidateSmallTickets` has finished.
344+
* @param firstTicketId first handled ticket id (different from the method param _firstTicketId if it was 0).
345+
* @param nextTicketId the first remaining (not handled) ticket id, or 0 if the end of queue was reached.
346+
*/
347+
event RedemptionTicketsConsolidated(
348+
uint256 firstTicketId,
349+
uint256 nextTicketId
350+
);
351+
340352
/**
341353
* Due to lot size change, some dust was created for this agent during
342354
* redemption. Value `dustUBA` is the new amount of dust. Dust cannot be directly redeemed,
@@ -512,33 +524,18 @@ interface IAssetManagerEvents {
512524
uint256 safetyMinCollateralRatioBIPS
513525
);
514526

515-
/**
516-
* Collateral token has been marked as deprecated. After the timestamp `validUntil` passes, it will be
517-
* considered invalid and the agents who haven't switched their collateral before will be liquidated.
518-
*/
519-
event CollateralTypeDeprecated(
520-
uint8 collateralClass,
521-
address collateralToken,
522-
uint256 validUntil
523-
);
524-
525527
/**
526528
* Emergency pause was triggered.
527529
*/
528-
event EmergencyPauseTriggered(uint256 pausedUntil);
530+
event EmergencyPauseTriggered(
531+
EmergencyPause.Level externalLevel,
532+
uint256 externalPausedUntil,
533+
EmergencyPause.Level governanceLevel,
534+
uint256 governancePausedUntil
535+
);
529536

530537
/**
531538
* Emergency pause was canceled.
532539
*/
533540
event EmergencyPauseCanceled();
534-
535-
/**
536-
* Emergency pause transfers was triggered.
537-
*/
538-
event EmergencyPauseTransfersTriggered(uint256 pausedUntil);
539-
540-
/**
541-
* Emergency pause transfers was canceled.
542-
*/
543-
event EmergencyPauseTransfersCanceled();
544541
}

coston/data/AssetManagerSettings.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@ library AssetManagerSettings {
170170
// Shouldn't be much bigger than Flare data connector response time, so that payments can be confirmed without
171171
// extra wait. Should be smaller than confirmationByOthersAfterSeconds (e.g. less than 1 hour).
172172
// rate-limited
173-
uint64 __announcedUnderlyingConfirmationMinSeconds;
173+
uint64 __announcedUnderlyingConfirmationMinSeconds; // only storage placeholder
174174
// Minimum time from the moment token is deprecated to when it becomes invalid and agents still using
175175
// it as vault collateral get liquidated.
176176
// timelocked
177-
uint64 tokenInvalidationTimeMinSeconds;
177+
uint64 __tokenInvalidationTimeMinSeconds; // only storage placeholder
178178
// On some rare occasions (stuck minting), the agent has to unlock collateral.
179179
// For this, part of collateral corresponding to FTSO asset value is burned and the rest is released.
180180
// However, we cannot burn typical vault collateral (stablecoins), so the agent must buy them for NAT

coston/data/CollateralType.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ library CollateralType {
1818
IERC20 token;
1919
// Same as token.decimals(), when that exists.
2020
uint256 decimals;
21-
// Token invalidation time. Must be 0 on creation.
21+
// Token invalidation time. Should always be 0 since token invalidation is deprecated.
2222
uint256 validUntil;
2323
// When `true`, the FTSO with symbol `assetFtsoSymbol` returns asset price relative to this token
2424
// (such FTSO's will probably exist for major stablecoins).

coston/data/EmergencyPause.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.7.6 <0.9;
3+
4+
library EmergencyPause {
5+
enum Level {
6+
// Pause is not active.
7+
NONE,
8+
// Prevent starting mint, redeem, liquidation and core vault transfer/return.
9+
START_OPERATIONS,
10+
// Everything from START_OPERATIONS, plus prevent finishing or defulating already started mints and redeems.
11+
FULL,
12+
// Everything from FULL, plus prevent FAsset transfers.
13+
FULL_AND_TRANSFER
14+
}
15+
}

coston2/IAssetManager.sol

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {AvailableAgentInfo} from "./data/AvailableAgentInfo.sol";
1212
import {RedemptionTicketInfo} from "./data/RedemptionTicketInfo.sol";
1313
import {RedemptionRequestInfo} from "./data/RedemptionRequestInfo.sol";
1414
import {CollateralReservationInfo} from "./data/CollateralReservationInfo.sol";
15+
import {EmergencyPause} from "./data/EmergencyPause.sol";
1516
import {IAssetManagerEvents} from "./IAssetManagerEvents.sol";
1617
import {IAgentPing} from "./IAgentPing.sol";
1718
import {IRedemptionTimeExtension} from "./IRedemptionTimeExtension.sol";
@@ -96,22 +97,18 @@ interface IAssetManager is
9697
function emergencyPaused() external view returns (bool);
9798

9899
/**
99-
* The time when emergency pause mode will end automatically.
100-
*/
101-
function emergencyPausedUntil() external view returns (uint256);
102-
103-
////////////////////////////////////////////////////////////////////////////////////
104-
// Emergency pause transfers
105-
106-
/**
107-
* If true, the system is in emergency pause mode and most operations (mint, redeem, liquidate) are disabled.
100+
* Emergency pause level defines which operations are paused:
101+
* NONE - pause is not active,
102+
* START_OPERATIONS - prevent starting mint, redeem, liquidation (start/liquidate) and core vault transfer/return,
103+
* FULL - everything from START_OPERATIONS, plus prevent finishing or defulating already started mints and redeems,
104+
* FULL_AND_TRANSFER - everything from FULL, plus prevent FAsset transfers.
108105
*/
109-
function transfersEmergencyPaused() external view returns (bool);
106+
function emergencyPauseLevel() external view returns (EmergencyPause.Level);
110107

111108
/**
112109
* The time when emergency pause mode will end automatically.
113110
*/
114-
function transfersEmergencyPausedUntil() external view returns (uint256);
111+
function emergencyPausedUntil() external view returns (uint256);
115112

116113
////////////////////////////////////////////////////////////////////////////////////
117114
// Asset manager upgrading state
@@ -264,13 +261,6 @@ interface IAssetManager is
264261
string memory _name
265262
) external;
266263

267-
/**
268-
* If the current agent's vault collateral token gets deprecated, the agent must switch with this method.
269-
* NOTE: may only be called by the agent vault owner.
270-
* NOTE: at the time of switch, the agent must have enough of both collaterals in the vault.
271-
*/
272-
function switchVaultCollateral(address _agentVault, IERC20 _token) external;
273-
274264
/**
275265
* When current pool collateral token contract (WNat) is replaced by the method setPoolWNatCollateralType,
276266
* pools don't switch automatically. Instead, the agent must call this method that swaps old WNat tokens for
@@ -808,7 +798,7 @@ interface IAssetManager is
808798
);
809799

810800
////////////////////////////////////////////////////////////////////////////////////
811-
// Dust
801+
// Dust and small ticket management
812802

813803
/**
814804
* Due to the minting pool fees or after a lot size change by the governance,
@@ -824,6 +814,20 @@ interface IAssetManager is
824814
*/
825815
function convertDustToTicket(address _agentVault) external;
826816

817+
/**
818+
* If lot size is increased, there may be many tickets less than one lot in the queue.
819+
* In extreme cases, this could prevent redemptions, if there weren't any tickets above 1 lot
820+
* among the first `maxRedeemedTickets` tickets.
821+
* To fix this, call this method. It converts small tickets to dust and when the dust exceeds one lot
822+
* adds it to the ticket.
823+
* Since the method just cleans the redemption queue it can be called by anybody.
824+
* @param _firstTicketId if nonzero, the ticket id of starting ticket; if zero, the starting ticket will
825+
* be the redemption queue's first ticket id.
826+
* When the method finishes, it emits RedemptionTicketsConsolidated event with the nextTicketId
827+
* parameter. If it is nonzero, the method should be invoked again with this value as _firstTicketId.
828+
*/
829+
function consolidateSmallTickets(uint256 _firstTicketId) external;
830+
827831
////////////////////////////////////////////////////////////////////////////////////
828832
// Liquidation
829833

coston2/IAssetManagerEvents.sol

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >=0.7.6 <0.9;
33

4+
import {EmergencyPause} from "./data/EmergencyPause.sol";
5+
46
/**
57
* All asset manager events.
68
*/
@@ -337,6 +339,16 @@ interface IAssetManagerEvents {
337339
uint256 indexed redemptionTicketId
338340
);
339341

342+
/**
343+
* Method `consolidateSmallTickets` has finished.
344+
* @param firstTicketId first handled ticket id (different from the method param _firstTicketId if it was 0).
345+
* @param nextTicketId the first remaining (not handled) ticket id, or 0 if the end of queue was reached.
346+
*/
347+
event RedemptionTicketsConsolidated(
348+
uint256 firstTicketId,
349+
uint256 nextTicketId
350+
);
351+
340352
/**
341353
* Due to lot size change, some dust was created for this agent during
342354
* redemption. Value `dustUBA` is the new amount of dust. Dust cannot be directly redeemed,
@@ -512,33 +524,18 @@ interface IAssetManagerEvents {
512524
uint256 safetyMinCollateralRatioBIPS
513525
);
514526

515-
/**
516-
* Collateral token has been marked as deprecated. After the timestamp `validUntil` passes, it will be
517-
* considered invalid and the agents who haven't switched their collateral before will be liquidated.
518-
*/
519-
event CollateralTypeDeprecated(
520-
uint8 collateralClass,
521-
address collateralToken,
522-
uint256 validUntil
523-
);
524-
525527
/**
526528
* Emergency pause was triggered.
527529
*/
528-
event EmergencyPauseTriggered(uint256 pausedUntil);
530+
event EmergencyPauseTriggered(
531+
EmergencyPause.Level externalLevel,
532+
uint256 externalPausedUntil,
533+
EmergencyPause.Level governanceLevel,
534+
uint256 governancePausedUntil
535+
);
529536

530537
/**
531538
* Emergency pause was canceled.
532539
*/
533540
event EmergencyPauseCanceled();
534-
535-
/**
536-
* Emergency pause transfers was triggered.
537-
*/
538-
event EmergencyPauseTransfersTriggered(uint256 pausedUntil);
539-
540-
/**
541-
* Emergency pause transfers was canceled.
542-
*/
543-
event EmergencyPauseTransfersCanceled();
544541
}

coston2/data/AssetManagerSettings.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@ library AssetManagerSettings {
170170
// Shouldn't be much bigger than Flare data connector response time, so that payments can be confirmed without
171171
// extra wait. Should be smaller than confirmationByOthersAfterSeconds (e.g. less than 1 hour).
172172
// rate-limited
173-
uint64 __announcedUnderlyingConfirmationMinSeconds;
173+
uint64 __announcedUnderlyingConfirmationMinSeconds; // only storage placeholder
174174
// Minimum time from the moment token is deprecated to when it becomes invalid and agents still using
175175
// it as vault collateral get liquidated.
176176
// timelocked
177-
uint64 tokenInvalidationTimeMinSeconds;
177+
uint64 __tokenInvalidationTimeMinSeconds; // only storage placeholder
178178
// On some rare occasions (stuck minting), the agent has to unlock collateral.
179179
// For this, part of collateral corresponding to FTSO asset value is burned and the rest is released.
180180
// However, we cannot burn typical vault collateral (stablecoins), so the agent must buy them for NAT

coston2/data/CollateralType.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ library CollateralType {
1818
IERC20 token;
1919
// Same as token.decimals(), when that exists.
2020
uint256 decimals;
21-
// Token invalidation time. Must be 0 on creation.
21+
// Token invalidation time. Should always be 0 since token invalidation is deprecated.
2222
uint256 validUntil;
2323
// When `true`, the FTSO with symbol `assetFtsoSymbol` returns asset price relative to this token
2424
// (such FTSO's will probably exist for major stablecoins).

coston2/data/EmergencyPause.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.7.6 <0.9;
3+
4+
library EmergencyPause {
5+
enum Level {
6+
// Pause is not active.
7+
NONE,
8+
// Prevent starting mint, redeem, liquidation and core vault transfer/return.
9+
START_OPERATIONS,
10+
// Everything from START_OPERATIONS, plus prevent finishing or defulating already started mints and redeems.
11+
FULL,
12+
// Everything from FULL, plus prevent FAsset transfers.
13+
FULL_AND_TRANSFER
14+
}
15+
}

0 commit comments

Comments
 (0)