Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GaugeController: Add Owner and Manager Roles #279

Merged
merged 6 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
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 () => {
kamescg marked this conversation as resolved.
Show resolved Hide resolved
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 () => {
kamescg marked this conversation as resolved.
Show resolved Hide resolved
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 () => {
kamescg marked this conversation as resolved.
Show resolved Hide resolved
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