forked from bgd-labs/aave-governance-v3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request bgd-labs#36 from bgd-labs/feat/operational-payload…
…s-controller Feat/operational payloads controller
- Loading branch information
Showing
10 changed files
with
555 additions
and
29 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
## Permissioned payloads controller overview | ||
|
||
[PermissionedPayloadsController](https://www.notion.so/src/contracts/payloads/PermissionedPayloadsController.sol): This is an extension of the PayloadsController contract, that modifies it so that only accepted actors (PayloadManager) can register a payload. The objective of having such extension is so that allowed third parties to affect change into low risk parts of the protocol, using similar processeces as governance. For that a new Executor contract will be registered to this Permissioned Payloads Controller, that will hold limited permissions. | ||
At launch it will have permissions to change the LM programs. | ||
|
||
**Key points and differences from PayloadsController**: | ||
|
||
- Contract includes a payloads manager role with permission to create and cancel payloads. | ||
- Payload creation is permissioned: only the payloads manager can create payloads. | ||
- Contract has a guardian role to review created payloads and cancel them if incorrect or unrecognized. | ||
- The guardian can adjust the timelock within certain limits. | ||
- Payloads manager and guardian have equal permissions to cancel payloads. Payloads can be cancelled if not expired or executed. | ||
- Payload execution is permissionless. If the timelock has passed and the payload isn't cancelled or expired, anyone can execute it. The Aave-robot is responsible for executing payloads. | ||
- Executor holds permission emission admin role. | ||
|
||
**The execution process operates as follows**: | ||
|
||
1. A trusted entity creates a payload of any kind and submits it to the permissioned payloads controller. | ||
2. Payload creation is combined with queuing: once created, a payload is automatically queued. The payload ID returned from the createPayload() function can be used to cancel or execute the payload. | ||
3. The payload is assigned a timelock. During this timelock period, the guardian can verify the validity of the payload. If the payload is deemed invalid or unrecognized, the guardian can cancel it. The payloads manager also has the authority to cancel it. | ||
4. Once the timelock period ends and the payload is unlocked and not expired, anyone is permitted to execute it. | ||
|
||
![Permissioned payloads controller flow](./permissioned-payloads-controller-flow.jpg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
src/contracts/payloads/PermissionedPayloadsController.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {IPayloadsControllerCore} from './interfaces/IPayloadsControllerCore.sol'; | ||
import {PayloadsControllerCore} from './PayloadsControllerCore.sol'; | ||
import {PayloadsControllerUtils} from './PayloadsControllerUtils.sol'; | ||
import {WithPayloadsManager} from './WithPayloadsManager.sol'; | ||
import {IPermissionedPayloadsController} from './interfaces/IPermissionedPayloadsController.sol'; | ||
import {Errors} from '../libraries/Errors.sol'; | ||
|
||
/** | ||
* @title PermissionedPayloadsController | ||
* @author BGD Labs | ||
* @notice this contract contains the logic to execute payloads | ||
* without governance cycle but leaving the gap to review and cancel payloads. | ||
* @dev this contract is permissioned, only the payloads manager can create | ||
* and queue payloads. Also, not only guardian but also the payloads manager can cancel payloads. | ||
* @dev constants were adjusted as the governance cycle is no longer needed. | ||
* @dev owner and guardian are the same entity here. | ||
*/ | ||
contract PermissionedPayloadsController is | ||
PayloadsControllerCore, | ||
WithPayloadsManager, | ||
IPermissionedPayloadsController | ||
{ | ||
/// @inheritdoc IPermissionedPayloadsController | ||
function initialize( | ||
address guardian, | ||
address initialPayloadsManager, | ||
UpdateExecutorInput[] calldata executors | ||
) | ||
public | ||
override(PayloadsControllerCore, IPermissionedPayloadsController) | ||
initializer | ||
{ | ||
PayloadsControllerCore.initialize(guardian, guardian, executors); | ||
_updatePayloadsManager(initialPayloadsManager); | ||
} | ||
|
||
/// @inheritdoc IPayloadsControllerCore | ||
function MIN_EXECUTION_DELAY() | ||
public | ||
pure | ||
override(PayloadsControllerCore, IPayloadsControllerCore) | ||
returns (uint40) | ||
{ | ||
return 0; | ||
} | ||
|
||
/// @inheritdoc IPayloadsControllerCore | ||
function MAX_EXECUTION_DELAY() | ||
public | ||
pure | ||
override(PayloadsControllerCore, IPayloadsControllerCore) | ||
returns (uint40) | ||
{ | ||
return 7 days; | ||
} | ||
|
||
/// @inheritdoc IPayloadsControllerCore | ||
function cancelPayload( | ||
uint40 payloadId | ||
) | ||
external | ||
override(PayloadsControllerCore, IPayloadsControllerCore) | ||
onlyPayloadsManagerOrGuardian | ||
{ | ||
_cancelPayload(payloadId); | ||
} | ||
|
||
/// @inheritdoc IPayloadsControllerCore | ||
function createPayload( | ||
ExecutionAction[] calldata actions | ||
) | ||
public | ||
override(PayloadsControllerCore, IPayloadsControllerCore) | ||
onlyPayloadsManager | ||
returns (uint40) | ||
{ | ||
uint40 payloadId = super.createPayload(actions); | ||
_queuePayload( | ||
payloadId, | ||
PayloadsControllerUtils.AccessControl.Level_1, | ||
type(uint40).max | ||
); | ||
return payloadId; | ||
} | ||
|
||
/// @inheritdoc IPayloadsControllerCore | ||
function updateExecutors( | ||
UpdateExecutorInput[] calldata | ||
) | ||
external | ||
pure | ||
override(PayloadsControllerCore, IPayloadsControllerCore) | ||
{ | ||
revert(Errors.FUNCTION_NOT_SUPPORTED); | ||
} | ||
|
||
/** | ||
* @notice Sets the execution delay | ||
* @param delay The new execution delay to be set | ||
*/ | ||
function setExecutionDelay(uint40 delay) external onlyGuardian { | ||
require( | ||
delay >= MIN_EXECUTION_DELAY() && delay <= MAX_EXECUTION_DELAY(), | ||
Errors.INVALID_EXECUTOR_DELAY | ||
); | ||
_accessLevelToExecutorConfig[PayloadsControllerUtils.AccessControl.Level_1] | ||
.delay = delay; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {IWithPayloadsManager} from './interfaces/IWithPayloadsManager.sol'; | ||
import {OwnableWithGuardian} from 'solidity-utils/contracts/access-control/OwnableWithGuardian.sol'; | ||
import {Errors} from '../libraries/Errors.sol'; | ||
|
||
/** | ||
* @title WithPayloadsManager | ||
* @author BGD Labs | ||
* @dev Contract module which provides a basic access control mechanism, where | ||
* there are accounts (owner, guardian, and payloads manager) which can be granted | ||
* exclusive access to specific functions. | ||
* @notice By default, all the roles will be assigned to the one that deploys the contract. This | ||
* can later be changed with appropriate functions. | ||
*/ | ||
contract WithPayloadsManager is OwnableWithGuardian, IWithPayloadsManager { | ||
address private _payloadsManager; | ||
|
||
constructor() { | ||
_updatePayloadsManager(_msgSender()); | ||
} | ||
|
||
modifier onlyPayloadsManager() { | ||
require(_msgSender() == payloadsManager(), Errors.ONLY_BY_PAYLOADS_MANAGER); | ||
_; | ||
} | ||
|
||
modifier onlyPayloadsManagerOrGuardian() { | ||
require( | ||
_msgSender() == payloadsManager() || _msgSender() == guardian(), | ||
Errors.ONLY_BY_PAYLOADS_MANAGER_OR_GUARDIAN | ||
); | ||
_; | ||
} | ||
|
||
/// @inheritdoc IWithPayloadsManager | ||
function payloadsManager() public view returns (address) { | ||
return _payloadsManager; | ||
} | ||
|
||
/// @inheritdoc IWithPayloadsManager | ||
function updatePayloadsManager( | ||
address newPayloadsManager | ||
) external onlyOwnerOrGuardian { | ||
_updatePayloadsManager(newPayloadsManager); | ||
} | ||
|
||
/** | ||
* @dev updates the address of the payloads manager | ||
* @param newPayloadsManager the new address of the payloads manager. | ||
*/ | ||
function _updatePayloadsManager(address newPayloadsManager) internal { | ||
_payloadsManager = newPayloadsManager; | ||
emit PayloadsManagerUpdated(newPayloadsManager); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/contracts/payloads/interfaces/IPermissionedPayloadsController.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {IPayloadsControllerCore} from "./IPayloadsControllerCore.sol"; | ||
import {IWithPayloadsManager} from "./IWithPayloadsManager.sol"; | ||
import {PayloadsControllerUtils} from "../PayloadsControllerUtils.sol"; | ||
|
||
/** | ||
* @title IPermissionedPayloadsController | ||
* @author BGD Labs | ||
* @notice interface containing the objects, events and methods definitions of the IPermissionedPayloadsController contract | ||
*/ | ||
interface IPermissionedPayloadsController is IPayloadsControllerCore, IWithPayloadsManager { | ||
/** | ||
* @notice method to initialize the contract with starter params. Only callable by proxy | ||
* @param guardian address of the guardian. With permissions to call certain methods | ||
* @param initialPayloadsManager address of the initial payload manager | ||
* @param executors array of executor configurations | ||
*/ | ||
function initialize( | ||
address guardian, | ||
address initialPayloadsManager, | ||
UpdateExecutorInput[] calldata executors | ||
) external; | ||
|
||
function setExecutionDelay(uint40 delay) external; | ||
} |
Oops, something went wrong.