Skip to content

Commit

Permalink
fix: rename gho bucket steward
Browse files Browse the repository at this point in the history
  • Loading branch information
CheyenneAtapour committed Aug 8, 2024
1 parent 8b8c5e9 commit 77b4d54
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import {IGhoToken} from '../gho/interfaces/IGhoToken.sol';
import {RiskCouncilControlled} from './RiskCouncilControlled.sol';
import {IGhoBucketCapacitySteward} from './interfaces/IGhoBucketCapacitySteward.sol';
import {IGhoBucketSteward} from './interfaces/IGhoBucketSteward.sol';

/**
* @title GhoBucketCapacitySteward
* @title GhoBucketSteward
* @author Aave Labs
* @notice Helper contract for managing bucket capacities of controlled facilitators
* @dev Only the Risk Council is able to action contract's functions, based on specific conditions that have been agreed upon with the community.
* @dev Requires role GHO_TOKEN_BUCKET_MANAGER_ROLE on GhoToken
*/
contract GhoBucketCapacitySteward is Ownable, RiskCouncilControlled, IGhoBucketCapacitySteward {
contract GhoBucketSteward is Ownable, RiskCouncilControlled, IGhoBucketSteward {
using EnumerableSet for EnumerableSet.AddressSet;

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
uint256 public constant MINIMUM_DELAY = 2 days;

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
address public immutable GHO_TOKEN;

mapping(address => uint40) internal _facilitatorsBucketCapacityTimelocks;
Expand Down Expand Up @@ -55,7 +55,7 @@ contract GhoBucketCapacitySteward is Ownable, RiskCouncilControlled, IGhoBucketC
_transferOwnership(owner);
}

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
function updateFacilitatorBucketCapacity(
address facilitator,
uint128 newBucketCapacity
Expand All @@ -72,7 +72,7 @@ contract GhoBucketCapacitySteward is Ownable, RiskCouncilControlled, IGhoBucketC
IGhoToken(GHO_TOKEN).setFacilitatorBucketCapacity(facilitator, newBucketCapacity);
}

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
function setControlledFacilitator(
address[] memory facilitatorList,
bool approve
Expand All @@ -87,19 +87,19 @@ contract GhoBucketCapacitySteward is Ownable, RiskCouncilControlled, IGhoBucketC
}
}

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
function getControlledFacilitators() external view returns (address[] memory) {
return _controlledFacilitators.values();
}

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
function getFacilitatorBucketCapacityTimelock(
address facilitator
) external view returns (uint40) {
return _facilitatorsBucketCapacityTimelocks[facilitator];
}

/// @inheritdoc IGhoBucketCapacitySteward
/// @inheritdoc IGhoBucketSteward
function RISK_COUNCIL() public view override returns (address) {
return COUNCIL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
pragma solidity ^0.8.10;

/**
* @title IGhoBucketCapacitySteward
* @title IGhoBucketSteward
* @author Aave Labs
* @notice Defines the basic interface of the GhoBucketCapacitySteward
* @notice Defines the basic interface of the GhoBucketSteward
*/
interface IGhoBucketCapacitySteward {
interface IGhoBucketSteward {
/**
* @notice Updates the bucket capacity of facilitator, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
Expand Down
4 changes: 2 additions & 2 deletions src/test/TestGhoBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ import {UpgradeableLockReleaseTokenPool, UpgradeableTokenPool} from '../contract
import {RateLimiter} from '../contracts/misc/deps/RateLimiter.sol';
import {IGhoCcipSteward} from '../contracts/misc/interfaces/IGhoCcipSteward.sol';
import {GhoCcipSteward} from '../contracts/misc/GhoCcipSteward.sol';
import {GhoBucketCapacitySteward} from '../contracts/misc/GhoBucketCapacitySteward.sol';
import {GhoBucketSteward} from '../contracts/misc/GhoBucketSteward.sol';

contract TestGhoBase is Test, Constants, Events {
using WadRayMath for uint256;
Expand Down Expand Up @@ -140,7 +140,7 @@ contract TestGhoBase is Test, Constants, Events {
GhoAaveSteward GHO_AAVE_STEWARD;
GhoCcipSteward GHO_CCIP_STEWARD;
GhoGsmSteward GHO_GSM_STEWARD;
GhoBucketCapacitySteward GHO_BUCKET_CAPACITY_STEWARD;
GhoBucketSteward GHO_BUCKET_STEWARD;
MockPoolDataProvider MOCK_POOL_DATA_PROVIDER;

FixedRateStrategyFactory FIXED_RATE_STRATEGY_FACTORY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,71 @@ pragma solidity ^0.8.0;

import './TestGhoBase.t.sol';

contract TestGhoBucketCapacitySteward is TestGhoBase {
contract TestGhoBucketSteward is TestGhoBase {
function setUp() public {
// Deploy Gho Bucket Capacity Steward
GHO_BUCKET_CAPACITY_STEWARD = new GhoBucketCapacitySteward(
SHORT_EXECUTOR,
address(GHO_TOKEN),
RISK_COUNCIL
);
GHO_BUCKET_STEWARD = new GhoBucketSteward(SHORT_EXECUTOR, address(GHO_TOKEN), RISK_COUNCIL);
address[] memory controlledFacilitators = new address[](2);
controlledFacilitators[0] = address(GHO_ATOKEN);
controlledFacilitators[1] = address(GHO_GSM);
vm.prank(SHORT_EXECUTOR);
GHO_BUCKET_CAPACITY_STEWARD.setControlledFacilitator(controlledFacilitators, true);
GHO_BUCKET_STEWARD.setControlledFacilitator(controlledFacilitators, true);

/// @dev Since block.timestamp starts at 0 this is a necessary condition (block.timestamp > `MINIMUM_DELAY`) for the timelocked contract methods to work.
vm.warp(GHO_BUCKET_CAPACITY_STEWARD.MINIMUM_DELAY() + 1);
vm.warp(GHO_BUCKET_STEWARD.MINIMUM_DELAY() + 1);

// Grant roles
GHO_TOKEN.grantRole(GHO_TOKEN_BUCKET_MANAGER_ROLE, address(GHO_BUCKET_CAPACITY_STEWARD));
GHO_TOKEN.grantRole(GHO_TOKEN_BUCKET_MANAGER_ROLE, address(GHO_BUCKET_STEWARD));
}

function testConstructor() public {
assertEq(GHO_BUCKET_CAPACITY_STEWARD.owner(), SHORT_EXECUTOR);
assertEq(GHO_BUCKET_CAPACITY_STEWARD.GHO_TOKEN(), address(GHO_TOKEN));
assertEq(GHO_BUCKET_CAPACITY_STEWARD.RISK_COUNCIL(), RISK_COUNCIL);
assertEq(GHO_BUCKET_STEWARD.owner(), SHORT_EXECUTOR);
assertEq(GHO_BUCKET_STEWARD.GHO_TOKEN(), address(GHO_TOKEN));
assertEq(GHO_BUCKET_STEWARD.RISK_COUNCIL(), RISK_COUNCIL);

address[] memory controlledFacilitators = GHO_BUCKET_CAPACITY_STEWARD
.getControlledFacilitators();
address[] memory controlledFacilitators = GHO_BUCKET_STEWARD.getControlledFacilitators();
assertEq(controlledFacilitators.length, 2);

uint40 facilitatorTimelock = GHO_BUCKET_CAPACITY_STEWARD.getFacilitatorBucketCapacityTimelock(
uint40 facilitatorTimelock = GHO_BUCKET_STEWARD.getFacilitatorBucketCapacityTimelock(
controlledFacilitators[0]
);
assertEq(facilitatorTimelock, 0);
}

function testRevertConstructorInvalidExecutor() public {
vm.expectRevert('INVALID_OWNER');
new GhoBucketCapacitySteward(address(0), address(0x002), address(0x003));
new GhoBucketSteward(address(0), address(0x002), address(0x003));
}

function testRevertConstructorInvalidGhoToken() public {
vm.expectRevert('INVALID_GHO_TOKEN');
new GhoBucketCapacitySteward(address(0x001), address(0), address(0x003));
new GhoBucketSteward(address(0x001), address(0), address(0x003));
}

function testRevertConstructorInvalidRiskCouncil() public {
vm.expectRevert('INVALID_RISK_COUNCIL');
new GhoBucketCapacitySteward(address(0x001), address(0x002), address(0));
new GhoBucketSteward(address(0x001), address(0x002), address(0));
}

function testChangeOwnership() public {
address NEW_OWNER = makeAddr('NEW_OWNER');
assertEq(GHO_BUCKET_CAPACITY_STEWARD.owner(), SHORT_EXECUTOR);
assertEq(GHO_BUCKET_STEWARD.owner(), SHORT_EXECUTOR);
vm.prank(SHORT_EXECUTOR);
GHO_BUCKET_CAPACITY_STEWARD.transferOwnership(NEW_OWNER);
assertEq(GHO_BUCKET_CAPACITY_STEWARD.owner(), NEW_OWNER);
GHO_BUCKET_STEWARD.transferOwnership(NEW_OWNER);
assertEq(GHO_BUCKET_STEWARD.owner(), NEW_OWNER);
}

function testChangeOwnershipRevert() public {
vm.expectRevert('Ownable: new owner is the zero address');
vm.prank(SHORT_EXECUTOR);
GHO_BUCKET_CAPACITY_STEWARD.transferOwnership(address(0));
GHO_BUCKET_STEWARD.transferOwnership(address(0));
}

function testUpdateFacilitatorBucketCapacity() public {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
vm.prank(RISK_COUNCIL);
uint128 newBucketCapacity = uint128(currentBucketCapacity) + 1;
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
newBucketCapacity
);
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(address(GHO_ATOKEN), newBucketCapacity);
(uint256 capacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
assertEq(newBucketCapacity, capacity);
}
Expand All @@ -84,39 +76,31 @@ contract TestGhoBucketCapacitySteward is TestGhoBase {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
uint128 newBucketCapacity = uint128(currentBucketCapacity * 2);
vm.prank(RISK_COUNCIL);
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
newBucketCapacity
);
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(address(GHO_ATOKEN), newBucketCapacity);
(uint256 capacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
assertEq(capacity, newBucketCapacity);
}

function testUpdateFacilitatorBucketCapacityTimelock() public {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
vm.prank(RISK_COUNCIL);
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
uint128(currentBucketCapacity) + 1
);
uint40 timelock = GHO_BUCKET_CAPACITY_STEWARD.getFacilitatorBucketCapacityTimelock(
address(GHO_ATOKEN)
);
uint40 timelock = GHO_BUCKET_STEWARD.getFacilitatorBucketCapacityTimelock(address(GHO_ATOKEN));
assertEq(timelock, block.timestamp);
}

function testUpdateFacilitatorBucketCapacityAfterTimelock() public {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
vm.prank(RISK_COUNCIL);
uint128 newBucketCapacity = uint128(currentBucketCapacity) + 1;
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
newBucketCapacity
);
skip(GHO_BUCKET_CAPACITY_STEWARD.MINIMUM_DELAY() + 1);
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(address(GHO_ATOKEN), newBucketCapacity);
skip(GHO_BUCKET_STEWARD.MINIMUM_DELAY() + 1);
uint128 newBucketCapacityAfterTimelock = newBucketCapacity + 1;
vm.prank(RISK_COUNCIL);
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
newBucketCapacityAfterTimelock
);
Expand All @@ -127,19 +111,19 @@ contract TestGhoBucketCapacitySteward is TestGhoBase {
function testRevertUpdateFacilitatorBucketCapacityIfUnauthorized() public {
vm.expectRevert('INVALID_CALLER');
vm.prank(ALICE);
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(address(GHO_ATOKEN), 123);
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(address(GHO_ATOKEN), 123);
}

function testRevertUpdateFaciltatorBucketCapacityIfUpdatedTooSoon() public {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
vm.prank(RISK_COUNCIL);
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
uint128(currentBucketCapacity) + 1
);
vm.prank(RISK_COUNCIL);
vm.expectRevert('DEBOUNCE_NOT_RESPECTED');
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
uint128(currentBucketCapacity) + 2
);
Expand All @@ -149,23 +133,23 @@ contract TestGhoBucketCapacitySteward is TestGhoBase {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_GSM_4626));
vm.prank(RISK_COUNCIL);
vm.expectRevert('FACILITATOR_NOT_CONTROLLED');
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_GSM_4626),
uint128(currentBucketCapacity) + 1
);
}

function testRevertUpdateFacilitatorBucketCapacityIfStewardLostBucketManagerRole() public {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
GHO_TOKEN.revokeRole(GHO_TOKEN_BUCKET_MANAGER_ROLE, address(GHO_BUCKET_CAPACITY_STEWARD));
GHO_TOKEN.revokeRole(GHO_TOKEN_BUCKET_MANAGER_ROLE, address(GHO_BUCKET_STEWARD));
vm.expectRevert(
AccessControlErrorsLib.MISSING_ROLE(
GHO_TOKEN_BUCKET_MANAGER_ROLE,
address(GHO_BUCKET_CAPACITY_STEWARD)
address(GHO_BUCKET_STEWARD)
)
);
vm.prank(RISK_COUNCIL);
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
uint128(currentBucketCapacity) + 1
);
Expand All @@ -175,7 +159,7 @@ contract TestGhoBucketCapacitySteward is TestGhoBase {
(uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN));
vm.prank(RISK_COUNCIL);
vm.expectRevert('INVALID_BUCKET_CAPACITY_UPDATE');
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
uint128(currentBucketCapacity * 2) + 1
);
Expand All @@ -186,34 +170,27 @@ contract TestGhoBucketCapacitySteward is TestGhoBase {
vm.prank(RISK_COUNCIL);
uint128 newBucketCapacity = uint128(currentBucketCapacity) - 1;
vm.expectRevert('INVALID_BUCKET_CAPACITY_UPDATE');
GHO_BUCKET_CAPACITY_STEWARD.updateFacilitatorBucketCapacity(
address(GHO_ATOKEN),
newBucketCapacity
);
GHO_BUCKET_STEWARD.updateFacilitatorBucketCapacity(address(GHO_ATOKEN), newBucketCapacity);
}

function testSetControlledFacilitatorAdd() public {
address[] memory oldControlledFacilitators = GHO_BUCKET_CAPACITY_STEWARD
.getControlledFacilitators();
address[] memory oldControlledFacilitators = GHO_BUCKET_STEWARD.getControlledFacilitators();
address[] memory newGsmList = new address[](1);
newGsmList[0] = address(GHO_GSM_4626);
vm.prank(SHORT_EXECUTOR);
GHO_BUCKET_CAPACITY_STEWARD.setControlledFacilitator(newGsmList, true);
address[] memory newControlledFacilitators = GHO_BUCKET_CAPACITY_STEWARD
.getControlledFacilitators();
GHO_BUCKET_STEWARD.setControlledFacilitator(newGsmList, true);
address[] memory newControlledFacilitators = GHO_BUCKET_STEWARD.getControlledFacilitators();
assertEq(newControlledFacilitators.length, oldControlledFacilitators.length + 1);
assertTrue(_contains(newControlledFacilitators, address(GHO_GSM_4626)));
}

function testSetControlledFacilitatorsRemove() public {
address[] memory oldControlledFacilitators = GHO_BUCKET_CAPACITY_STEWARD
.getControlledFacilitators();
address[] memory oldControlledFacilitators = GHO_BUCKET_STEWARD.getControlledFacilitators();
address[] memory disableGsmList = new address[](1);
disableGsmList[0] = address(GHO_GSM);
vm.prank(SHORT_EXECUTOR);
GHO_BUCKET_CAPACITY_STEWARD.setControlledFacilitator(disableGsmList, false);
address[] memory newControlledFacilitators = GHO_BUCKET_CAPACITY_STEWARD
.getControlledFacilitators();
GHO_BUCKET_STEWARD.setControlledFacilitator(disableGsmList, false);
address[] memory newControlledFacilitators = GHO_BUCKET_STEWARD.getControlledFacilitators();
assertEq(newControlledFacilitators.length, oldControlledFacilitators.length - 1);
assertFalse(_contains(newControlledFacilitators, address(GHO_GSM)));
}
Expand All @@ -223,6 +200,6 @@ contract TestGhoBucketCapacitySteward is TestGhoBase {
vm.prank(RISK_COUNCIL);
address[] memory newGsmList = new address[](1);
newGsmList[0] = address(GHO_GSM_4626);
GHO_BUCKET_CAPACITY_STEWARD.setControlledFacilitator(newGsmList, true);
GHO_BUCKET_STEWARD.setControlledFacilitator(newGsmList, true);
}
}

0 comments on commit 77b4d54

Please sign in to comment.