Fujicracy / fuji-v2

Cross-chain money market aggregator
https://fuji-v2-frontend.vercel.app
15 stars 10 forks source link

[Epic] Access Control and Roles #78

Closed iafhurtado closed 1 year ago

iafhurtado commented 1 year ago

The goal of this ticket is to have access controls and roles implemented in a consistent way across the whole system. This is a ticket to track progress.

1. Chief

2. BorrowingVault and YieldVault

3. FujiOracle

4. AddrMapper - check the comments below

brozorec commented 1 year ago
Contract Permissioned functions Allowed caller Notes
BorrowingVault
pause() Chief From pauseAllVaults() in case of emergency.
pause() MultiSig
unpause() Chief From unpauseAllVaults().
unpause() MultiSig
setOracle() MultiSig -timelock
setMaxLtv() MultiSig-timelock
setLiqRatio() MultiSig-timelock
liquidate() LiquidationManager A new contract that manages a list of allowed liquidators. liquidate() needs to call the Chief to check if msg.sender has a "Liquidator" role.
rebalance() RebalanceManager A new contract that manages a list of allowed rebalancers and handles flashloan logic. rebalance() needs to call the Chief to check if msg.sender has a "Rebalancer" role.
harvest() HarvestManager A new contract that manages a list of allowed harvesters and handles specificities for each protocol. harvest() needs to call the Chief to check if msg.sender has a "Harvester" role.
setProviders() MultiSig-timelock
setActiveProvider() RebalanceManager A new contract that manages a list of allowed rebalancers and handles flashloan logic. setActiveProvider() needs to call the Chief to check if msg.sender has a "Rebalancer" role.
YieldVault
pause() Chief from pauseAllVaults() in case of emergency
pause() MultiSig
unpause() Chief from unpauseAllVaults()
unpause() MultiSig
rebalance() RebalanceManager a contract that manages a list of allowed rebalancers and handles flashloan logic
harvest() HarvestManager a contract that manages a list of allowed harvesters and handles specificities for each protocol
VaultDeployer
_registerVault() Chief Internal function called by every vault factory.
FujiOracle
setPriceFeed() MultiSig-timelock
Chief
deployVault() EOA We start with only allowed EOAs that can depoy a new vault and eventually, open it for any EOA.
pauseAllVaults() MultiSig
unpauseAllVaults() MultiSig
grantRole() MultiSig ref: https://docs.openzeppelin.com/contracts/4.x/api/access
revokeRole() MultiSig ref: https://docs.openzeppelin.com/contracts/4.x/api/access
addToAllowed() MultiSig Controls allowed factories for vaults.
removeFromAllowed() MultiSig Controls allowed factories for vaults.
AddrMapper *
setMapping() MultiSig
setNestedMapping() MultiSig
Flasher
N/A N/A
Swapper
N/A N/A

@DaigaroCota plz check

0xdcota commented 1 year ago

@brozorec , first awesome job on the detailing of the functions and the intended role. Some comments:

  1. For pause() I am thinking we also add Externally Owned Accounts (yours or mine) for quick reaction. Or an alternative is that we create a "Security Multisg" including 1 signer from the auditors of the code. To also have them have some response responsibility. We can discuss the last point further.
  2. Excellent and completely agree in the need of pauseAllVaults() and viceverse. Only question I will have, is if we introduce and array to iterate over? Or we keep track of all vaults off-chain?
  3. I added Timelock to some of the functions that in the future I suggest should have this time component to allow people to react if they would like to react.
  4. For the deployVault() function in the Chief, in response to the comments, I would rather advocate to this be done by a future governance process instead of just "any EOA". The reason is that users could bloat our system with not relevant vaults, better to perhaps have a vetting process, because there is some risk associated with setting up the providers. Is not like Curve in where they are the lowest block and all risk lies within their code.
  5. For the AddrMapper you think perhaps we include a double nested mapping? For example: (string) providerName => ( addressKey1 => (addressKey2 => IBT equivalent address)) I believe this way the mapper can be the same address and just keep adding maps.
brozorec commented 1 year ago

@iafhurtado @DaigaroCota fyi this ticket's description got updated with the needed details and an action plan.

brozorec commented 1 year ago

For pause() I am thinking we also add Externally Owned Accounts (yours or mine) for quick reaction.

  1. I suggest creating a Pauser role that can be attributed to EOAs.

Excellent and completely agree in the need of pauseAllVaults() and viceverse. Only question I will have, is if we introduce and array to iterate over? Or we keep track of all vaults off-chain?

  1. Yes, we keep them in an array in the contract.

  2. I agree

  3. I agree

  4. Added specs in the ticket description.

@DaigaroCota

iafhurtado commented 1 year ago

Time estimation around 2 days

0xdcota commented 1 year ago

@brozorec After getting into the writing of the actual implementations, I have the following comments: 1.- Openzeppelin-AccessControl.sol can be used entirely to replace the Ownable.sol. DEFAULT_ADMIN_ROLE can be used instead of onlyOwner. This will avoid inheriting Ownable, and hence having two "access-control" implementations in Chief. 2.- I followed the naming convention for roles that was established by OpenZeppelin. NAME_ROLE. 3.- I decided to split the roles into two groups. The "core roles" are the ones that will be hardcoded in the contract system. Any additional role can be created by the intended createRole() functions. Additionally, I assumed this createRole() is intended to add roles in the future, like we did with the game roles in V1-nft-game. The reason to split it, is because it simplifies the modifier call, and costs less gas to know the roles before hand. That way, you can do, chief.hasRole(who, role) and is simple at runtime. Otherwise, If not hardcoded, you need to check; role exists? or some type of getRole(this).

brozorec commented 1 year ago
  1. and 2. very well
  2. I started looking into it, very good ideas overall :+1: I have some feedback on the organization of the new code, I'll write it down directly in #94 @DaigaroCota