Skip to content

Commit 07c64d5

Browse files
committed
feat: add library with errors and update test set up
1 parent c66b36b commit 07c64d5

File tree

5 files changed

+112
-43
lines changed

5 files changed

+112
-43
lines changed

src/contracts/facilitators/gsm/GsmL2.sol

+26-25
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {SignatureChecker} from '@openzeppelin/contracts/utils/cryptography/Signa
99
import {SafeCast} from '@openzeppelin/contracts/utils/math/SafeCast.sol';
1010
import {AccessControl} from '@openzeppelin/contracts/access/AccessControl.sol';
1111

12+
import {Errors} from 'src/contracts/facilitators/gsm/libraries/Errors.sol';
1213
import {IGhoFacilitator} from 'src/contracts/gho/interfaces/IGhoFacilitator.sol';
1314
import {IGhoToken} from 'src/contracts/gho/interfaces/IGhoToken.sol';
1415
import {IGsmPriceStrategy} from 'src/contracts/facilitators/gsm/priceStrategy/interfaces/IGsmPriceStrategy.sol';
@@ -76,15 +77,15 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
7677
* @dev Require GSM to not be frozen for functions marked by this modifier
7778
*/
7879
modifier notFrozen() {
79-
require(!_isFrozen, GsmFrozen());
80+
require(!_isFrozen, Errors.GSM_FROZEN);
8081
_;
8182
}
8283

8384
/**
8485
* @dev Require GSM to not be seized for functions marked by this modifier
8586
*/
8687
modifier notSeized() {
87-
require(!_isSeized, GsmSeized());
88+
require(!_isSeized, Errors.GSM_SEIZED);
8889
_;
8990
}
9091

@@ -95,11 +96,11 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
9596
* @param priceStrategy The address of the price strategy
9697
*/
9798
constructor(address ghoToken, address underlyingAsset, address priceStrategy) EIP712('GSM', '1') {
98-
require(ghoToken != address(0), InvalidZeroAddress());
99-
require(underlyingAsset != address(0), InvalidZeroAddress());
99+
require(ghoToken != address(0), Errors.INVALID_ZERO_ADDRESS);
100+
require(underlyingAsset != address(0), Errors.INVALID_ZERO_ADDRESS);
100101
require(
101102
IGsmPriceStrategy(priceStrategy).UNDERLYING_ASSET() == underlyingAsset,
102-
InvalidPriceStrategy()
103+
Errors.INVALID_PRICE_STRATEGY
103104
);
104105
GHO_TOKEN = ghoToken;
105106
UNDERLYING_ASSET = underlyingAsset;
@@ -119,7 +120,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
119120
uint128 exposureCap,
120121
address liquidityProvider
121122
) external initializer {
122-
require(admin != address(0), InvalidZeroAddress());
123+
require(admin != address(0), Errors.INVALID_ZERO_ADDRESS);
123124
_grantRole(DEFAULT_ADMIN_ROLE, admin);
124125
_grantRole(CONFIGURATOR_ROLE, admin);
125126
_updateGhoTreasury(ghoTreasury);
@@ -143,7 +144,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
143144
uint256 deadline,
144145
bytes calldata signature
145146
) external notFrozen notSeized returns (uint256, uint256) {
146-
require(deadline >= block.timestamp, SignatureExpired());
147+
require(deadline >= block.timestamp, Errors.SIG_EXPIRED);
147148
bytes32 digest = keccak256(
148149
abi.encode(
149150
'\x19\x01',
@@ -154,7 +155,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
154155
);
155156
require(
156157
SignatureChecker.isValidSignatureNow(originator, digest, signature),
157-
InvalidSignature()
158+
Errors.INVALID_SIG
158159
);
159160

160161
return _buyAsset(originator, minAmount, receiver);
@@ -176,7 +177,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
176177
uint256 deadline,
177178
bytes calldata signature
178179
) external notFrozen notSeized returns (uint256, uint256) {
179-
require(deadline >= block.timestamp, SignatureExpired());
180+
require(deadline >= block.timestamp, Errors.SIG_EXPIRED);
180181
bytes32 digest = keccak256(
181182
abi.encode(
182183
'\x19\x01',
@@ -187,7 +188,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
187188
);
188189
require(
189190
SignatureChecker.isValidSignatureNow(originator, digest, signature),
190-
InvalidSignature()
191+
Errors.INVALID_SIG
191192
);
192193

193194
return _sellAsset(originator, maxAmount, receiver);
@@ -199,14 +200,14 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
199200
address to,
200201
uint256 amount
201202
) external onlyRole(TOKEN_RESCUER_ROLE) {
202-
require(amount > 0, InvalidAmount());
203+
require(amount > 0, Errors.INVALID_AMOUNT);
203204
if (token == GHO_TOKEN) {
204205
uint256 rescuableBalance = IERC20(token).balanceOf(address(this)) - _accruedFees;
205-
require(rescuableBalance >= amount, 'INSUFFICIENT_GHO_TO_RESCUE');
206+
require(rescuableBalance >= amount, Errors.INSUFFICIENT_GHO_RESC);
206207
}
207208
if (token == UNDERLYING_ASSET) {
208209
uint256 rescuableBalance = IERC20(token).balanceOf(address(this)) - _currentExposure;
209-
require(rescuableBalance >= amount, 'INSUFFICIENT_EXOGENOUS_ASSET_TO_RESCUE');
210+
require(rescuableBalance >= amount, Errors.INSUFFICIENT_EXO_RESC);
210211
}
211212
IERC20(token).safeTransfer(to, amount);
212213
emit TokensRescued(token, to, amount);
@@ -215,9 +216,9 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
215216
/// @inheritdoc IGsm
216217
function setSwapFreeze(bool enable) external onlyRole(SWAP_FREEZER_ROLE) {
217218
if (enable) {
218-
require(!_isFrozen, GsmFrozen());
219+
require(!_isFrozen, Errors.GSM_FROZEN);
219220
} else {
220-
require(_isFrozen, 'GSM_ALREADY_UNFROZEN');
221+
require(_isFrozen, Errors.GSM_UNFROZEN);
221222
}
222223
_isFrozen = enable;
223224
emit SwapFreeze(msg.sender, enable);
@@ -240,8 +241,8 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
240241

241242
/// @inheritdoc IGsm
242243
function burnAfterSeize(uint256 amount) external onlyRole(LIQUIDATOR_ROLE) returns (uint256) {
243-
require(_isSeized, GsmNotSeized());
244-
require(amount > 0, InvalidAmount());
244+
require(_isSeized, Errors.GSM_NOT_SEIZED);
245+
require(amount > 0, Errors.INVALID_AMOUNT);
245246

246247
if (amount > _ghoLiquidity) {
247248
amount = _ghoLiquidity;
@@ -256,7 +257,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
256257

257258
/// @inheritdoc IGsmL2
258259
function provideLiquidity(uint256 amount) external {
259-
require(msg.sender == _liquidityProvider, InvalidLiquidityProvider());
260+
require(msg.sender == _liquidityProvider, Errors.INVALID_LIQ_PROVIDER);
260261

261262
_ghoLiquidity += amount.toUint128();
262263
IGhoToken(GHO_TOKEN).transferFrom(msg.sender, address(this), amount);
@@ -420,8 +421,8 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
420421

421422
_beforeBuyAsset(originator, assetAmount, receiver);
422423

423-
require(assetAmount > 0, InvalidAmount());
424-
require(_currentExposure >= assetAmount, InsufficientAvailableExogenousLiquidity());
424+
require(assetAmount > 0, Errors.INVALID_AMOUNT);
425+
require(_currentExposure >= assetAmount, Errors.INSUFFICIENT_EXO_LIQ);
425426

426427
_currentExposure -= assetAmount.toUint128();
427428
_ghoLiquidity += ghoSold.toUint128();
@@ -465,8 +466,8 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
465466

466467
_beforeSellAsset(originator, assetAmount, receiver);
467468

468-
require(assetAmount > 0, InvalidAmount());
469-
require(_currentExposure + assetAmount <= _exposureCap, ExogenousAssetExposureTooHigh());
469+
require(assetAmount > 0, Errors.INVALID_AMOUNT);
470+
require(_currentExposure + assetAmount <= _exposureCap, Errors.EXO_LIQ_HIGH);
470471

471472
_currentExposure += assetAmount.toUint128();
472473
_ghoLiquidity -= ghoBought.toUint128();
@@ -570,10 +571,10 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
570571

571572
/**
572573
* @dev Updates Liquidity Provider
573-
* @param exposureCap The address of the liquidty provider for the GSM
574+
* @param liquidityProvider The address of the liquidty provider for the GSM
574575
*/
575576
function _updateLiquidityProvider(address liquidityProvider) internal {
576-
require(liquidityProvider != address(0), InvalidZeroAddress());
577+
require(liquidityProvider != address(0), Errors.INVALID_ZERO_ADDRESS);
577578
address oldLiquidityProvider = _liquidityProvider;
578579
_liquidityProvider = liquidityProvider;
579580
emit LiquidityProviderUpdated(oldLiquidityProvider, liquidityProvider);
@@ -584,7 +585,7 @@ contract GsmL2 is IGsm, IGsmL2, AccessControl, VersionedInitializable, EIP712 {
584585
* @param newGhoTreasury The address of the new GHO Treasury
585586
*/
586587
function _updateGhoTreasury(address newGhoTreasury) internal {
587-
require(newGhoTreasury != address(0), InvalidZeroAddress());
588+
require(newGhoTreasury != address(0), Errors.INVALID_ZERO_ADDRESS);
588589
address oldGhoTreasury = _ghoTreasury;
589590
_ghoTreasury = newGhoTreasury;
590591
emit GhoTreasuryUpdated(oldGhoTreasury, newGhoTreasury);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.10;
3+
4+
library Errors {
5+
string public constant INVALID_ZERO_ADDRESS = '1'; // Address cannot be the zero-address
6+
string public constant GSM_FROZEN = '2'; // The GSM is currently frozen and swaps cannot be performed
7+
string public constant GSM_UNFROZEN = '3'; // The GSM is already unfrozen
8+
string public constant GSM_SEIZED = '4'; // The GSM has been seized and is no longer operational
9+
string public constant GSM_NOT_SEIZED = '5'; // The GSM has been seized and is no longer operational
10+
string public constant INVALID_PRICE_STRATEGY = '6'; // Invalid price strategy provided
11+
string public constant INVALID_SIG = '7'; // The signature is invalid
12+
string public constant SIG_EXPIRED = '8'; // The signature deadline has passed
13+
string public constant INSUFFICIENT_EXO_RESC = '9'; // Insufficient exogenous asset balance to perform rescue
14+
string public constant INSUFFICIENT_GHO_RESC = '10'; // Insufficient GHO balance to perform rescue
15+
string public constant INVALID_AMOUNT = '11'; // Amount must be greater than zero
16+
string public constant INVALID_LIQ_PROVIDER = '12'; // Only approved provider can supply liquidity
17+
string public constant INSUFFICIENT_EXO_LIQ = '13'; // Insufficient available exogenous liquidity
18+
string public constant EXO_LIQ_HIGH = '14'; // Exogenous asset exposure too high
19+
}

src/test/TestGhoBase.t.sol

+22
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {WadRayMath} from '@aave/core-v3/contracts/protocol/libraries/math/WadRay
2121
import {MockAclManager} from './mocks/MockAclManager.sol';
2222
import {MockConfigurator} from './mocks/MockConfigurator.sol';
2323
import {MockFlashBorrower} from './mocks/MockFlashBorrower.sol';
24+
import {MockLiquidityProvider} from './mocks/MockLiquidityProvider.sol';
2425
import {MockGsmV2} from './mocks/MockGsmV2.sol';
2526
import {MockPool} from './mocks/MockPool.sol';
2627
import {MockAddressesProvider} from './mocks/MockAddressesProvider.sol';
@@ -115,6 +116,7 @@ contract TestGhoBase is Test, Constants, Events {
115116
MockERC4626 USDC_4626_TOKEN;
116117
MockPool POOL;
117118
MockAclManager ACL_MANAGER;
119+
MockLiquidityProvider LIQUIDITY_PROVIDER;
118120
MockAddressesProvider PROVIDER;
119121
MockConfigurator CONFIGURATOR;
120122
PriceOracle PRICE_ORACLE;
@@ -126,6 +128,7 @@ contract TestGhoBase is Test, Constants, Events {
126128
GhoDiscountRateStrategy GHO_DISCOUNT_STRATEGY;
127129
MockFlashBorrower FLASH_BORROWER;
128130
Gsm GHO_GSM;
131+
GsmL2 GHO_GSM_L2;
129132
Gsm4626 GHO_GSM_4626;
130133
FixedPriceStrategy GHO_GSM_FIXED_PRICE_STRATEGY;
131134
FixedPriceStrategy4626 GHO_GSM_4626_FIXED_PRICE_STRATEGY;
@@ -160,6 +163,7 @@ contract TestGhoBase is Test, Constants, Events {
160163
MOCK_POOL_DATA_PROVIDER = new MockPoolDataProvider(address(PROVIDER));
161164
POOL = new MockPool(IPoolAddressesProvider(address(PROVIDER)));
162165
CONFIGURATOR = new MockConfigurator(IPool(POOL));
166+
LIQUIDITY_PROVIDER = new MockLiquidityProvider();
163167
PRICE_ORACLE = new PriceOracle();
164168
PROVIDER.setPool(address(POOL));
165169
PROVIDER.setConfigurator(address(CONFIGURATOR));
@@ -268,14 +272,32 @@ contract TestGhoBase is Test, Constants, Events {
268272
address(USDC_TOKEN),
269273
address(GHO_GSM_FIXED_PRICE_STRATEGY)
270274
);
275+
GsmL2 gsmL2 = new GsmL2(
276+
address(GHO_TOKEN),
277+
address(USDC_TOKEN),
278+
address(GHO_GSM_FIXED_PRICE_STRATEGY)
279+
);
271280
AdminUpgradeabilityProxy gsmProxy = new AdminUpgradeabilityProxy(
272281
address(gsm),
273282
SHORT_EXECUTOR,
274283
''
275284
);
285+
AdminUpgradeabilityProxy gsmProxyL2 = new AdminUpgradeabilityProxy(
286+
address(gsmL2),
287+
SHORT_EXECUTOR,
288+
''
289+
);
276290
GHO_GSM = Gsm(address(gsmProxy));
291+
GHO_GSM_L2 = GsmL2(address(gsmProxyL2));
277292

278293
GHO_GSM.initialize(address(this), TREASURY, DEFAULT_GSM_USDC_EXPOSURE);
294+
GHO_GSM_L2.initialize(
295+
address(this),
296+
TREASURY,
297+
DEFAULT_GSM_USDC_EXPOSURE,
298+
address(LIQUIDITY_PROVIDER)
299+
);
300+
279301
GHO_GSM_4626 = new Gsm4626(
280302
address(GHO_TOKEN),
281303
address(USDC_4626_TOKEN),

0 commit comments

Comments
 (0)