Skip to content

Commit

Permalink
roles rearranged
Browse files Browse the repository at this point in the history
  • Loading branch information
pum committed Aug 23, 2023
1 parent 9b996e6 commit db41764
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 146 deletions.
32 changes: 15 additions & 17 deletions contracts/VaultsFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "./IVault.sol";
contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {
address public immutable weth;

address public vaultsImplementation;
address public defaultVaultImplementation;
uint256 public unwrapDelay;

address public feeReceiver;
Expand All @@ -21,8 +21,7 @@ contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {

// Role identifiers for pausing, deploying, and admin actions
bytes32 public constant PAUSE_ROLE = keccak256("PAUSE_ROLE");
bytes32 public constant UNPAUSE_ROLE = keccak256("UNPAUSE_ROLE");
bytes32 public constant DEPLOY_ROLE = keccak256("DEPLOY_ROLE");
bytes32 public constant TEAM_ROLE = keccak256("TEAM_ROLE");

event VaultDeployed(IVault vaultAddress);
event VaultPaused(IVault vaultAddress);
Expand All @@ -41,28 +40,27 @@ contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {

constructor(
address weth_,
address vaultsImplementationAddress_,
address vaultImplementationAddress_,
uint256 unwrapDelay_,
address rolesAddr_,
address initialFeeReceiver_,
uint256 initialFeeBasisPoints_
) {
weth = weth_;
vaultsImplementation = vaultsImplementationAddress_;
defaultVaultImplementation = vaultImplementationAddress_;
unwrapDelay = unwrapDelay_;

_setupRole(DEFAULT_ADMIN_ROLE, rolesAddr_);
_setupRole(PAUSE_ROLE, rolesAddr_);
_setupRole(UNPAUSE_ROLE, rolesAddr_);
_setupRole(DEPLOY_ROLE, rolesAddr_);
_setupRole(TEAM_ROLE, rolesAddr_);

_setFeeReceiver(initialFeeReceiver_);
_setFeeBasisPoints(initialFeeBasisPoints_);
}

function deployVault(address underlyingToken_, string memory name_, string memory symbol_) external onlyRole(DEPLOY_ROLE) returns (IVault result) {
function deployVault(address underlyingToken_, string memory name_, string memory symbol_) external onlyRole(TEAM_ROLE) returns (IVault result) {
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
vaultsImplementation,
defaultVaultImplementation,
getRoleMember(DEFAULT_ADMIN_ROLE, 0),
""
);
Expand All @@ -82,7 +80,7 @@ contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {
emit VaultPaused(vault_);
}

function unpauseVault(IVault vaultAddress_) external onlyRole(UNPAUSE_ROLE) isVault(vaultAddress_) {
function unpauseVault(IVault vaultAddress_) external onlyRole(DEFAULT_ADMIN_ROLE) isVault(vaultAddress_) {
delete pausedVaults[vaultAddress_];
emit VaultUnpaused(vaultAddress_);
}
Expand All @@ -92,7 +90,7 @@ contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {
emit AllVaultsPaused();
}

function unpauseAllVaults() external onlyRole(UNPAUSE_ROLE) {
function unpauseAllVaults() external onlyRole(DEFAULT_ADMIN_ROLE) {
allVaultsPaused = false;
emit AllVaultsUnpaused();
}
Expand All @@ -105,9 +103,9 @@ contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {
unwrapDelay = unwrapDelay_;
}

function setVaultsImplementation(address vaultsImplementation_) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(vaultsImplementation_ != address(0), "VAULTS: ZERO_ADDRESS");
vaultsImplementation = vaultsImplementation_;
function setDefaultVaultImplementation(address vaultImplementation_) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(vaultImplementation_ != address(0), "VAULTS: ZERO_ADDRESS");
defaultVaultImplementation = vaultImplementation_;
}

function emergencyWithdrawFromVault(IVault vaultAddress_, address to_, uint256 amount_) external onlyRole(DEFAULT_ADMIN_ROLE) {
Expand All @@ -119,15 +117,15 @@ contract VaultsFactory is IVaultsFactory, AccessControlEnumerable {
}

function _setFeeBasisPoints(uint256 feeBasisPoints_) internal {
require(feeBasisPoints_ <= 10000, "VAULTS: EXCESSIVE_FEE_PERCENT"); // Max of 10000 basis points
require(feeBasisPoints_ <= 200, "VAULTS: EXCESSIVE_FEE_PERCENT"); // Max 2%
feeBasisPoints = feeBasisPoints_;
}

function setFeeReceiver(address feeReceiver_) external onlyRole(DEFAULT_ADMIN_ROLE) {
function setFeeReceiver(address feeReceiver_) external onlyRole(TEAM_ROLE) {
_setFeeReceiver(feeReceiver_);
}

function setFeeBasisPoints(uint256 feeBasisPoints_) external onlyRole(DEFAULT_ADMIN_ROLE) {
function setFeeBasisPoints(uint256 feeBasisPoints_) external onlyRole(TEAM_ROLE) {
_setFeeBasisPoints(feeBasisPoints_);
}
}
38 changes: 17 additions & 21 deletions test/Vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ const BN = ethers.BigNumber.from;
const ETH = (x) => ethers.utils.parseEther(x.toString())

describe("Vault", function () {
let vaultsFactory, vaultsImplementation, weth;
let deployer, adminRole, pauseRole, unpauseRole, deployRole, feeReceiver, nobody, addr1, addr2;
let vaultsFactory, vaultImplementation, weth;
let deployer, adminRole, pauseRole, teamRole, feeReceiver, nobody, addr1, addr2;

let token1, token2, token3;
let vault1, vault2, vault3, wethVault;

let VaultsFactoryFactory;

let PAUSE_ROLE, UNPAUSE_ROLE, DEPLOY_ROLE, ADMIN_ROLE;
let PAUSE_ROLE, TEAM_ROLE, ADMIN_ROLE;

beforeEach(async function () {
[deployer, adminRole, pauseRole, unpauseRole, deployRole, feeReceiver, nobody, addr1, addr2] = await ethers.getSigners();
[deployer, adminRole, pauseRole, teamRole, feeReceiver, nobody, addr1, addr2] = await ethers.getSigners();

const WethFactory = await ethers.getContractFactory("MockWeth");
const TokenFactory = await ethers.getContractFactory("MockERC20");
Expand All @@ -35,35 +35,33 @@ describe("Vault", function () {
token3 = await TokenFactory.deploy("Mock Token3", "MTK3", 33, ETH("1000"));
await token3.deployed();

vaultsImplementation = await VaultImplementationFactory.deploy();
await vaultsImplementation.deployed();
vaultImplementation = await VaultImplementationFactory.deploy();
await vaultImplementation.deployed();

vaultsFactory = await VaultsFactoryFactory.deploy(weth.address, vaultsImplementation.address, 3600, adminRole.address, ZERO_ADDRESS, 0);
vaultsFactory = await VaultsFactoryFactory.deploy(weth.address, vaultImplementation.address, 3600, adminRole.address, ZERO_ADDRESS, 0);
await vaultsFactory.deployed();

PAUSE_ROLE = await vaultsFactory.PAUSE_ROLE();
UNPAUSE_ROLE = await vaultsFactory.UNPAUSE_ROLE();
DEPLOY_ROLE = await vaultsFactory.DEPLOY_ROLE();
TEAM_ROLE = await vaultsFactory.TEAM_ROLE();
ADMIN_ROLE = await vaultsFactory.DEFAULT_ADMIN_ROLE();

// Setting roles for pauseRole, unpauseRole, deployRole
// Setting roles for pauseRole, teamRole
await vaultsFactory.connect(adminRole).grantRole(PAUSE_ROLE, pauseRole.address);
await vaultsFactory.connect(adminRole).grantRole(UNPAUSE_ROLE, unpauseRole.address);
await vaultsFactory.connect(adminRole).grantRole(DEPLOY_ROLE, deployRole.address);
await vaultsFactory.connect(adminRole).grantRole(TEAM_ROLE, teamRole.address);

let tx = await vaultsFactory.connect(deployRole).deployVault(token1.address, "", "");
let tx = await vaultsFactory.connect(teamRole).deployVault(token1.address, "", "");
const vault1addr = (await tx.wait()).events[3].args.vaultAddress;
vault1 = await ethers.getContractAt('VaultImplementation', vault1addr)

tx = await vaultsFactory.connect(deployRole).deployVault(token1.address, "", "");
tx = await vaultsFactory.connect(teamRole).deployVault(token1.address, "", "");
const vault2addr = (await tx.wait()).events[3].args.vaultAddress;
vault2 = await ethers.getContractAt('VaultImplementation', vault2addr)

tx = await vaultsFactory.connect(deployRole).deployVault(token1.address, "", "");
tx = await vaultsFactory.connect(teamRole).deployVault(token1.address, "", "");
const vault3addr = (await tx.wait()).events[3].args.vaultAddress;
vault3 = await ethers.getContractAt('VaultImplementation', vault3addr)

tx = await vaultsFactory.connect(deployRole).deployVault(weth.address, "", "");
tx = await vaultsFactory.connect(teamRole).deployVault(weth.address, "", "");
const wethVaultAddr = (await tx.wait()).events[3].args.vaultAddress;
wethVault = await ethers.getContractAt('VaultImplementation', wethVaultAddr)
});
Expand All @@ -80,7 +78,7 @@ describe("Vault", function () {
expect(await vault1proxy.connect(adminRole).admin()).to.equal(adminRole.address)


let tx = await vaultsFactory.connect(deployRole).deployVault(weth.address, "name", "symbol");
let tx = await vaultsFactory.connect(teamRole).deployVault(weth.address, "name", "symbol");
const vaultAddr = (await tx.wait()).events[3].args.vaultAddress;
const vault = await ethers.getContractAt('VaultImplementation', vaultAddr)

Expand Down Expand Up @@ -430,8 +428,7 @@ describe("Vault", function () {
await expect(vault1.connect(nobody).emergencyWithdraw(nobody.address, ETH(1))).to.be.revertedWith("VAULTS: NOT_PAUSED");
await expect(vaultsFactory.connect(nobody).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + nobody.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(pauseRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + pauseRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(unpauseRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + unpauseRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(deployRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + deployRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(teamRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + teamRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(adminRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("VAULTS: NOT_PAUSED");


Expand All @@ -442,8 +439,7 @@ describe("Vault", function () {
await expect(vault1.connect(nobody).emergencyWithdraw(nobody.address, ETH(1))).to.be.revertedWith("VAULTS: NOT_FACTORY_ADDRESS");
await expect(vaultsFactory.connect(nobody).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + nobody.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(pauseRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + pauseRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(unpauseRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + unpauseRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(deployRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + deployRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);
await expect(vaultsFactory.connect(teamRole).emergencyWithdrawFromVault(vault1.address, nobody.address, ETH(1))).to.be.revertedWith("AccessControl: account " + teamRole.address.toLowerCase() + " is missing role " + ADMIN_ROLE);


await expect(vaultsFactory.connect(adminRole).emergencyWithdrawFromVault(vault1.address, ZERO_ADDRESS, ETH(1))).to.be.revertedWith("VAULTS: ZERO_ADDRESS");
Expand Down

0 comments on commit db41764

Please sign in to comment.