Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/contracts/facilitators/gsm/GhoReserve.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import {IERC20} from 'aave-v3-origin/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import {SafeCast} from 'src/contracts/dependencies/openzeppelin-contracts/contracts/utils/math/SafeCast.sol';
import {IERC20} from 'aave-v3-origin/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
import {VersionedInitializable} from 'aave-v3-origin/contracts/misc/aave-upgradeability/VersionedInitializable.sol';
import {IGhoReserve} from 'src/contracts/facilitators/gsm/interfaces/IGhoReserve.sol';

Expand All @@ -15,6 +16,7 @@ import {IGhoReserve} from 'src/contracts/facilitators/gsm/interfaces/IGhoReserve
*/
contract GhoReserve is Ownable, VersionedInitializable, IGhoReserve {
using EnumerableSet for EnumerableSet.AddressSet;
using SafeCast for uint256;

/// @inheritdoc IGhoReserve
address public immutable GHO_TOKEN;
Expand Down Expand Up @@ -48,14 +50,14 @@ contract GhoReserve is Ownable, VersionedInitializable, IGhoReserve {
GhoUsage storage entity = _ghoUsage[msg.sender];
require(entity.limit >= entity.used + amount, 'LIMIT_EXCEEDED');

entity.used += uint128(amount);
entity.used += amount.toUint128();
IERC20(GHO_TOKEN).transfer(msg.sender, amount);
emit GhoUsed(msg.sender, amount);
}

/// @inheritdoc IGhoReserve
function restore(uint256 amount) external {
_ghoUsage[msg.sender].used -= uint128(amount);
_ghoUsage[msg.sender].used -= amount.toUint128();
IERC20(GHO_TOKEN).transferFrom(msg.sender, address(this), amount);
emit GhoRestored(msg.sender, amount);
}
Expand Down Expand Up @@ -83,7 +85,7 @@ contract GhoReserve is Ownable, VersionedInitializable, IGhoReserve {
/// @inheritdoc IGhoReserve
function setLimit(address entity, uint256 limit) external onlyOwner {
require(_entities.contains(entity), 'ENTITY_DOES_NOT_EXIST');
_ghoUsage[entity].limit = uint128(limit);
_ghoUsage[entity].limit = limit.toUint128();

emit GhoLimitUpdated(entity, limit);
}
Expand Down
24 changes: 12 additions & 12 deletions src/contracts/facilitators/gsm/Gsm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
IERC20(UNDERLYING_ASSET).safeTransfer(_ghoTreasury, underlyingBalance);
}

emit Seized(msg.sender, _ghoTreasury, underlyingBalance, _getUsedGho());
emit Seized(msg.sender, _ghoTreasury, underlyingBalance, _getUsed());
return underlyingBalance;
}

Expand All @@ -241,7 +241,7 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
require(_isSeized, 'GSM_NOT_SEIZED');
require(amount > 0, 'INVALID_AMOUNT');

uint256 usedGho = _getUsedGho();
uint256 usedGho = _getUsed();
if (amount > usedGho) {
amount = usedGho;
}
Expand Down Expand Up @@ -379,8 +379,8 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
}

/// @inheritdoc IGsm
function getUsedGho() external view returns (uint256) {
return _getUsedGho();
function getUsed() external view returns (uint256) {
return _getUsed();
}

/// @inheritdoc IGsm
Expand Down Expand Up @@ -553,6 +553,14 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
return (finalAssetAmount, finalGrossAmount - finalFee, finalGrossAmount, finalFee);
}

/**
* @dev Returns the amount of GHO currently used.
* @return The amount of GHO used
*/
function _getUsed() internal view returns (uint256) {
return IGhoReserve(_ghoReserve).getUsed(address(this));
}

/**
* @dev Returns the maximum amount of GHO that can be used.
* @return The usage limit of GHO
Expand All @@ -570,14 +578,6 @@ contract Gsm is AccessControl, VersionedInitializable, EIP712, IGsm {
return IGhoReserve(_ghoReserve).getUsage(address(this));
}

/**
* @dev Returns the amount of GHO currently used.
* @return The amount of GHO used
*/
function _getUsedGho() internal view returns (uint256) {
return IGhoReserve(_ghoReserve).getUsed(address(this));
}

/**
* @dev Updates Fee Strategy
* @param feeStrategy The address of the new Fee Strategy
Expand Down
6 changes: 3 additions & 3 deletions src/contracts/facilitators/gsm/Gsm4626.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ contract Gsm4626 is Gsm, IGsm4626 {
) external notSeized onlyRole(CONFIGURATOR_ROLE) returns (uint256) {
require(amount > 0, 'INVALID_AMOUNT');

uint256 usedGho = _getUsedGho();
uint256 usedGho = _getUsed();
(, uint256 deficit) = _getCurrentBacking(usedGho);
require(deficit > 0, 'NO_CURRENT_DEFICIT_BACKING');

Expand All @@ -63,7 +63,7 @@ contract Gsm4626 is Gsm, IGsm4626 {
) external notSeized onlyRole(CONFIGURATOR_ROLE) returns (uint256) {
require(amount > 0, 'INVALID_AMOUNT');

(, uint256 deficit) = _getCurrentBacking(_getUsedGho());
(, uint256 deficit) = _getCurrentBacking(_getUsed());
require(deficit > 0, 'NO_CURRENT_DEFICIT_BACKING');

uint128 deficitInUnderlying = IGsmPriceStrategy(PRICE_STRATEGY)
Expand Down Expand Up @@ -95,7 +95,7 @@ contract Gsm4626 is Gsm, IGsm4626 {

/// @inheritdoc IGsm4626
function getCurrentBacking() external view returns (uint256, uint256) {
return _getCurrentBacking(_getUsedGho());
return _getCurrentBacking(_getUsed());
}

/// @inheritdoc IGhoFacilitator
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/facilitators/gsm/OwnableFacilitator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
pragma solidity ^0.8.10;

import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
import {IOwnableFacilitator} from 'src/contracts/facilitators/gsm/interfaces/IOwnableFacilitator.sol';
import {IGhoToken} from 'src/contracts/gho/interfaces/IGhoToken.sol';
import {IOwnableFacilitator} from 'src/contracts/facilitators/gsm/interfaces/IOwnableFacilitator.sol';

/**
* @title OwnableFacilitator
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/facilitators/gsm/interfaces/IGsm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ interface IGsm is IAccessControl, IGhoFacilitator {
* @notice Returns the amount of GHO used by the GSM
* @return The amount of GHO used
*/
function getUsedGho() external view returns (uint256);
function getUsed() external view returns (uint256);

/**
* @notice Returns the maximum amount of GHO that can be used
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/facilitators/gsm/misc/SampleLiquidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract SampleLiquidator is Ownable {
*/
function triggerBurnAfterSeize(address gsm, uint256 amount) external onlyOwner returns (uint256) {
IERC20 ghoToken = IERC20(IGsm(gsm).GHO_TOKEN());
uint256 usedGho = IGsm(gsm).getUsedGho();
uint256 usedGho = IGsm(gsm).getUsed();
if (amount > usedGho) {
amount = usedGho;
}
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/TestGsm.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ contract TestGsm is TestGhoBase {
emit BuyAsset(ALICE, ALICE, 1e6, 1e18, 0);
GHO_GSM.buyAsset(1e6, ALICE);

uint256 usedGho = GHO_GSM.getUsedGho();
uint256 usedGho = GHO_GSM.getUsed();
assertEq(usedGho, DEFAULT_CAPACITY - 1e18, 'Unexpected GHO bucket level after buy');
assertEq(
GHO_TOKEN.balanceOf(ALICE),
Expand All @@ -759,7 +759,7 @@ contract TestGsm is TestGhoBase {
GHO_GSM.sellAsset(1e6, ALICE);
vm.stopPrank();

usedGho = GHO_GSM.getUsedGho();
usedGho = GHO_GSM.getUsed();
assertEq(usedGho, DEFAULT_CAPACITY, 'Unexpected GHO bucket level after second sell');
assertEq(
GHO_TOKEN.balanceOf(ALICE),
Expand Down Expand Up @@ -1332,7 +1332,7 @@ contract TestGsm is TestGhoBase {
uint256 seizedAmount = GHO_GSM.seize();
assertEq(seizedAmount, DEFAULT_GSM_USDX_AMOUNT, 'Unexpected seized amount');

uint256 usedGho = GHO_GSM.getUsedGho();
uint256 usedGho = GHO_GSM.getUsed();
assertTrue(usedGho > 0, 'Unexpected usedGho amount');

vm.expectRevert('FACILITATOR_BUCKET_LEVEL_NOT_ZERO');
Expand All @@ -1346,7 +1346,7 @@ contract TestGsm is TestGhoBase {
uint256 burnedAmount = GHO_GSM.burnAfterSeize(DEFAULT_GSM_GHO_AMOUNT);
vm.stopPrank();
assertEq(burnedAmount, DEFAULT_GSM_GHO_AMOUNT, 'Unexpected burned amount of GHO');
assertEq(GHO_GSM.getUsedGho(), 0, 'Unexpected amount of used GHO');
assertEq(GHO_GSM.getUsed(), 0, 'Unexpected amount of used GHO');
}

function testBurnAfterSeizeGreaterAmount() public {
Expand Down
14 changes: 7 additions & 7 deletions tests/unit/TestGsm4626.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ contract TestGsm4626 is TestGhoBase {
emit SellAsset(ALICE, ALICE, DEFAULT_GSM_USDX_EXPOSURE, DEFAULT_CAPACITY, 0);
GHO_GSM_4626.sellAsset(DEFAULT_GSM_USDX_EXPOSURE, ALICE);

uint256 usedGho = GHO_GSM_4626.getUsedGho();
uint256 usedGho = GHO_GSM_4626.getUsed();
uint256 ghoLimit = GHO_RESERVE.getLimit(address(GHO_GSM_4626));
assertEq(usedGho, ghoLimit, 'Unexpected GHO bucket level after initial sell');
assertEq(
Expand All @@ -407,7 +407,7 @@ contract TestGsm4626 is TestGhoBase {
emit BuyAsset(ALICE, ALICE, 1e6, 1e18, 0);
GHO_GSM_4626.buyAsset(1e6, ALICE);

usedGho = GHO_GSM_4626.getUsedGho();
usedGho = GHO_GSM_4626.getUsed();
assertEq(usedGho, DEFAULT_CAPACITY - 1e18, 'Unexpected GHO bucket level after buy');
assertEq(
GHO_TOKEN.balanceOf(ALICE),
Expand All @@ -423,7 +423,7 @@ contract TestGsm4626 is TestGhoBase {
GHO_GSM_4626.sellAsset(1e6, ALICE);
vm.stopPrank();

usedGho = GHO_GSM_4626.getUsedGho();
usedGho = GHO_GSM_4626.getUsed();
ghoLimit = GHO_RESERVE.getLimit(address(GHO_GSM_4626));
assertEq(usedGho, ghoLimit, 'Unexpected GHO bucket level after second sell');
assertEq(
Expand Down Expand Up @@ -934,7 +934,7 @@ contract TestGsm4626 is TestGhoBase {
uint256 burnedAmount = GHO_GSM_4626.burnAfterSeize(DEFAULT_GSM_GHO_AMOUNT);
vm.stopPrank();
assertEq(burnedAmount, DEFAULT_GSM_GHO_AMOUNT, 'Unexpected burned amount of GHO');
assertEq(GHO_GSM_4626.getUsedGho(), 0, 'Unexpected leftover amount of GHO');
assertEq(GHO_GSM_4626.getUsed(), 0, 'Unexpected leftover amount of GHO');
}

function testBurnAfterSeizeGreaterAmount() public {
Expand All @@ -948,7 +948,7 @@ contract TestGsm4626 is TestGhoBase {
uint256 seizedAmount = GHO_GSM_4626.seize();
assertEq(seizedAmount, DEFAULT_GSM_USDX_AMOUNT, 'Unexpected seized amount');

uint256 usedGho = GHO_GSM_4626.getUsedGho();
uint256 usedGho = GHO_GSM_4626.getUsed();
assertTrue(usedGho > 0, 'Unexpected usedGho amount');

vm.expectRevert('FACILITATOR_BUCKET_LEVEL_NOT_ZERO');
Expand Down Expand Up @@ -1043,12 +1043,12 @@ contract TestGsm4626 is TestGhoBase {
GHO_TOKEN.approve(address(GHO_GSM_4626), type(uint256).max);

uint256 balanceBefore = GHO_TOKEN.balanceOf(address(this));
uint256 usedGhoBefore = GHO_GSM_4626.getUsedGho();
uint256 usedGhoBefore = GHO_GSM_4626.getUsed();

uint256 ghoUsedForBacking = GHO_GSM_4626.backWithGho((DEFAULT_GSM_GHO_AMOUNT / 2) + 1);

uint256 balanceAfter = GHO_TOKEN.balanceOf(address(this));
uint256 usedGhoAfter = GHO_GSM_4626.getUsedGho();
uint256 usedGhoAfter = GHO_GSM_4626.getUsed();

assertEq(DEFAULT_GSM_GHO_AMOUNT / 2, ghoUsedForBacking);
assertEq(balanceBefore - balanceAfter, ghoUsedForBacking);
Expand Down
Loading