Skip to content

Commit

Permalink
GaugeController: Add Owner and Manager Roles (#279)
Browse files Browse the repository at this point in the history
* update(GaugeController.sol): inherit manageable and add authorization modifiers

* update(GaugeController.sol): add unit tests for access roles

* update(GaugeController.sol): add unit tests for manager roles

* fix

* update(GaugeController.sol): change function from public to external

* update(GaugeController.sol): removing comments
  • Loading branch information
kamescg committed Jun 2, 2022
1 parent e259f46 commit f68718a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 16 deletions.
26 changes: 11 additions & 15 deletions contracts/GaugeController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
pragma solidity 0.8.6;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@pooltogether/owner-manager-contracts/contracts/Ownable.sol";
import "@pooltogether/owner-manager-contracts/contracts/Manageable.sol";

import "./interfaces/IGaugeController.sol";
import "./interfaces/IGaugeReward.sol";
import "./libraries/TwabLib.sol";
import "./libraries/ExtendedSafeCastLib.sol";

contract GaugeController is IGaugeController, Ownable {
contract GaugeController is IGaugeController, Manageable {
using ExtendedSafeCastLib for uint256;

struct GaugeInfo {
Expand Down Expand Up @@ -183,7 +183,7 @@ contract GaugeController is IGaugeController, Ownable {
* @param _to Receivzer of the deposited tokens
* @param _amount Amount of tokens to be deposited
*/
function deposit(address _to, uint256 _amount) public {
function deposit(address _to, uint256 _amount) external {
balances[_to] += _amount;
token.transferFrom(msg.sender, address(this), _amount);
emit TokenDeposited(msg.sender, _amount);
Expand All @@ -193,7 +193,7 @@ contract GaugeController is IGaugeController, Ownable {
* @notice Withdraw tokens in GaugeController and increase User balance.
* @param _amount Amount of tokens to be withdrawn
*/
function withdraw(uint256 _amount) public {
function withdraw(uint256 _amount) external {
balances[msg.sender] -= _amount;
token.transfer(msg.sender, _amount);
emit TokenWithdrawn(msg.sender, _amount);
Expand All @@ -204,7 +204,7 @@ contract GaugeController is IGaugeController, Ownable {
* @param _gauge Address of the Gauge
* @param _amount Amount of tokens to be debited from the User balance and credited to the Gauge balance
*/
function increaseGauge(address _gauge, uint256 _amount) public requireGauge(_gauge) {
function increaseGauge(address _gauge, uint256 _amount) external requireGauge(_gauge) {
balances[msg.sender] -= _amount;
userGaugeBalance[msg.sender][_gauge] += _amount;
TwabLib.Account storage gaugeTwab = gaugeTwabs[_gauge];
Expand All @@ -221,7 +221,7 @@ contract GaugeController is IGaugeController, Ownable {
* @param _gauge Address of the Gauge
* @param _amount Amount of tokens to be debited from the Gauge balance and credited to the Gauge balance
*/
function decreaseGauge(address _gauge, uint256 _amount) public requireGauge(_gauge) {
function decreaseGauge(address _gauge, uint256 _amount) external requireGauge(_gauge) {
balances[msg.sender] += _amount;
userGaugeBalance[msg.sender][_gauge] -= _amount;
TwabLib.Account storage gaugeTwab = gaugeTwabs[_gauge];
Expand All @@ -233,31 +233,28 @@ contract GaugeController is IGaugeController, Ownable {
emit GaugeDecreased(msg.sender, _gauge, _amount);
}

/// @TODO: Add Governance/Executive authorization modifier/function.
/**
* @notice Add new gauge with "1e18" scale to the GaugeController.
* @param _gauge Address of the Gauge
*/
function addGauge(address _gauge) public {
function addGauge(address _gauge) external onlyOwner {
_addGaugeWithScale(_gauge, 1 ether);
}

/// @TODO: Add Governance/Executive authorization modifier/function.
/**
* @notice Add new gauge and target scale to the GaugeController.
* @param _gauge Address of new Gauge
* @param _scale Amount to scale new Gauge by
*/
function addGaugeWithScale(address _gauge, uint256 _scale) public {
function addGaugeWithScale(address _gauge, uint256 _scale) external onlyOwner {
_addGaugeWithScale(_gauge, _scale);
}

/// @TODO: Add Governance/Executive authorization modifier/function.
/**
* @notice Remove gauge from the GaugeController.
* @param _gauge Address of existing Gauge
*/
function removeGauge(address _gauge) public {
function removeGauge(address _gauge) external onlyOwner {
TwabLib.Account storage gaugeScaleTwab = gaugeScaleTwabs[_gauge];
TwabLib.AccountDetails memory twabDetails = gaugeScaleTwab.details;
(
Expand All @@ -271,19 +268,18 @@ contract GaugeController is IGaugeController, Ownable {
* @notice Set GaugeReward contract
* @param _gaugeReward Address of the GaugeReward contract
*/
function setGaugeReward(IGaugeReward _gaugeReward) external onlyOwner {
function setGaugeReward(IGaugeReward _gaugeReward) external onlyManagerOrOwner {
require(address(_gaugeReward) != address(0), "GC/GaugeReward-not-zero-address");
gaugeReward = _gaugeReward;
emit GaugeRewardSet(_gaugeReward);
}

/// @TODO: Add Governance/Executive authorization modifier/function.
/**
* @notice Set Gauge target scale.
* @param _gauge Address of existing Gauge
* @param _scale Amount to scale existing Gauge by
*/
function setGaugeScale(address _gauge, uint256 _scale) public {
function setGaugeScale(address _gauge, uint256 _scale) external onlyManagerOrOwner {
TwabLib.Account storage gaugeScaleTwab = gaugeScaleTwabs[_gauge];
TwabLib.AccountDetails memory twabDetails = gaugeScaleTwab.details;
if (twabDetails.balance > _scale) {
Expand Down
77 changes: 76 additions & 1 deletion test/GaugeController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const { parseEther: toWei } = utils;

describe('GaugeController', () => {
let owner: SignerWithAddress;
let manager: SignerWithAddress;
let wallet2: SignerWithAddress;
let GaugeController: Contract;
let GaugeReward: MockContract;
let Token: Contract;
Expand All @@ -23,7 +25,7 @@ describe('GaugeController', () => {
const gaugeAddress = '0x0000000000000000000000000000000000000001';

before(async () => {
[owner] = await getSigners();
[owner, manager, wallet2] = await getSigners();
GaugeControllerFactory = await ethers.getContractFactory('GaugeController');
GaugeRewardArtifact = await artifacts.readArtifact('GaugeReward');
TokenFactory = await ethers.getContractFactory('ERC20Mintable');
Expand All @@ -41,6 +43,7 @@ describe('GaugeController', () => {
GaugeReward = await deployMockContract(owner, GaugeRewardArtifact.abi);

await GaugeController.setGaugeReward(GaugeReward.address);
await GaugeController.setManager(manager.address);
});

/**
Expand Down Expand Up @@ -160,6 +163,29 @@ describe('GaugeController', () => {
});
});

/**
* @description Test addGauge(address _to) function
* -= Expected Behavior =-
* 1. require the `msg.sender` to be authorized to add a gauge
* 2. require the `gauge` DOES NOT exist
* 3. increase `gaugeTwab` TWAB with `1e18`
* 4. update the `gaugeTwab.details` with the updated `twabDetails` object
* 5. emit a AddGaugeWithScale event
*/
describe('addGauge(address _to)', () => {
it('should SUCCEED to add gauge to the gaugeScaleTwabs mapping', async () => {
await GaugeController.addGauge(gaugeAddress);
expect(await GaugeController.getGaugeScaleBalance(gaugeAddress)).to.eq(
'1000000000000000000',
);
});

it('should FAIL to execute BECAUSE of unauthorized access', async () => {
const unauthorized = GaugeController.connect(wallet2);
expect(unauthorized.addGauge(gaugeAddress)).to.be.revertedWith('Ownable/caller-not-owner');
});
});

/**
* @description Test addGaugeWithScale(address _to, uint256 _scale) function
* -= Expected Behavior =-
Expand All @@ -176,6 +202,11 @@ describe('GaugeController', () => {
'1000000000000000000',
);
});

it('should FAIL to execute BECAUSE of unauthorized access', async () => {
const unauthorized = GaugeController.connect(wallet2);
expect(unauthorized.addGaugeWithScale(gaugeAddress, toWei('1'))).to.be.revertedWith('Ownable/caller-not-owner');
});
});

/**
Expand All @@ -192,6 +223,11 @@ describe('GaugeController', () => {
await GaugeController.removeGauge(gaugeAddress);
expect(await GaugeController.getGaugeScaleBalance(gaugeAddress)).to.eq('0');
});

it('should FAIL to execute BECAUSE of unauthorized access', async () => {
const unauthorized = GaugeController.connect(wallet2);
expect(unauthorized.removeGauge(gaugeAddress)).to.be.revertedWith('Ownable/caller-not-owner');
});
});

/**
Expand Down Expand Up @@ -220,8 +256,47 @@ describe('GaugeController', () => {
'500000000000000000',
);
});

it('should SUCCEED to DECREASE the scale on EXISTING gauge from MANAGER role', async () => {
await GaugeController.addGauge(gaugeAddress);
const gauge = GaugeController.connect(manager);
await gauge.setGaugeScale(gaugeAddress, toWei('0.5'));
expect(await GaugeController.getGaugeScaleBalance(gaugeAddress)).to.eq(
'500000000000000000',
);
});

it('should FAIL to execute BECAUSE of unauthorized access', async () => {
await GaugeController.addGauge(gaugeAddress);
const unauthorized = GaugeController.connect(wallet2);
expect(unauthorized.setGaugeScale(gaugeAddress, toWei('2'))).to.be.revertedWith('Manageable/caller-not-manager-or-owner');
});
});

describe('setGaugeReward(IGaugeReward _gaugeReward)', () => {
it('should SUCCEED to SET a new GaugeReward address', async () => {
await GaugeController.addGauge(gaugeAddress);
await GaugeController.setGaugeReward('0x0000000000000000000000000000000000000001');
expect(await GaugeController.gaugeReward()).to.eq(
'0x0000000000000000000000000000000000000001',
);
});

it('should SUCCEED to SET a new GaugeReward address from MANAGER role', async () => {
await GaugeController.addGauge(gaugeAddress);
const gauge = GaugeController.connect(manager);
await gauge.setGaugeReward('0x0000000000000000000000000000000000000001');
expect(await GaugeController.gaugeReward()).to.eq(
'0x0000000000000000000000000000000000000001',
);
});

it('should FAIL to execute BECAUSE of unauthorized access', async () => {
const unauthorized = GaugeController.connect(wallet2);
expect(unauthorized.setGaugeReward('0x0000000000000000000000000000000000000001')).to.be.revertedWith('Manageable/caller-not-manager-or-owner');
});
})

/**
* @description Test getGaugeBalance(address _gauge) function
* -= Expected Behavior =-
Expand Down

0 comments on commit f68718a

Please sign in to comment.