Skip to content

Commit

Permalink
Registry: Implement stateless property (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
facuspagnuolo committed Jun 21, 2023
1 parent c9bf227 commit 72571ee
Show file tree
Hide file tree
Showing 17 changed files with 157 additions and 59 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ jobs:
uses: ./.github/actions/setup
- name: Build
run: yarn build

2 changes: 2 additions & 0 deletions .github/workflows/ci-authorizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-authorizer test
2 changes: 2 additions & 0 deletions .github/workflows/ci-deployer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-deployer test
2 changes: 2 additions & 0 deletions .github/workflows/ci-fee-controller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-fee-controller test
2 changes: 2 additions & 0 deletions .github/workflows/ci-helpers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-helpers test
4 changes: 4 additions & 0 deletions .github/workflows/ci-price-oracle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-price-oracle test

Expand All @@ -41,6 +43,8 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test mainnet
run: yarn workspace @mimic-fi/v3-price-oracle test:mainnet
- name: Test polygon
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci-registry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-registry test
2 changes: 2 additions & 0 deletions .github/workflows/ci-smart-vault.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-smart-vault test
2 changes: 2 additions & 0 deletions .github/workflows/ci-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up environment
uses: ./.github/actions/setup
- name: Build
run: yarn build
- name: Test
run: yarn workspace @mimic-fi/v3-tasks test
16 changes: 10 additions & 6 deletions packages/deployer/contracts/Deployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ contract Deployer {

/**
* @dev Task params
* @param custom Whether the implementation is custom or not, if it is it won't be checked with Mimic's Registry
* @param impl Address of the task implementation to be used
* @param initializeData Call-data to initialize the new task instance
*/
struct TaskParams {
bool custom;
address impl;
bytes initializeData;
}
Expand All @@ -102,7 +104,7 @@ contract Deployer {
* @dev Deploys a new authorizer instance
*/
function deployAuthorizer(string memory namespace, string memory name, AuthorizerParams memory params) external {
address instance = _deployClone(namespace, name, params.impl);
address instance = _deployClone(namespace, name, params.impl, true);
Authorizer(instance).initialize(params.owners);
emit AuthorizerDeployed(namespace, name, instance, params.impl);
}
Expand All @@ -111,7 +113,7 @@ contract Deployer {
* @dev Deploys a new smart vault instance
*/
function deploySmartVault(string memory namespace, string memory name, SmartVaultParams memory params) external {
address payable instance = payable(_deployClone(namespace, name, params.impl));
address payable instance = payable(_deployClone(namespace, name, params.impl, true));
SmartVault(instance).initialize(params.authorizer, params.priceOracle, params.priceFeedParams);
emit SmartVaultDeployed(namespace, name, instance, params.impl);
}
Expand All @@ -120,20 +122,22 @@ contract Deployer {
* @dev Deploys a new task instance
*/
function deployTask(string memory namespace, string memory name, TaskParams memory params) external {
address instance = _deployClone(namespace, name, params.impl);
address instance = _deployClone(namespace, name, params.impl, !params.custom);
if (params.initializeData.length > 0) instance.functionCall(params.initializeData, 'DEPLOYER_TASK_INIT_FAILED');
emit TaskDeployed(namespace, name, instance, params.impl);
}

/**
* @dev Deploys a new clone using CREATE3
*/
function _deployClone(string memory namespace, string memory name, address implementation)
function _deployClone(string memory namespace, string memory name, address implementation, bool check)
internal
returns (address)
{
require(registry.isRegistered(implementation), 'DEPLOYER_IMPL_NOT_REGISTERED');
require(!registry.isDeprecated(implementation), 'DEPLOYER_IMPL_DEPRECATED');
if (check) {
require(registry.isRegistered(implementation), 'DEPLOYER_IMPL_NOT_REGISTERED');
require(!registry.isDeprecated(implementation), 'DEPLOYER_IMPL_DEPRECATED');
}

bytes memory bytecode = abi.encodePacked(
hex'3d602d80600a3d3981f3363d3d373d3d3d363d73',
Expand Down
12 changes: 6 additions & 6 deletions packages/deployer/test/Deployer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Deployer', () => {

context('when the implementation is registered', () => {
beforeEach('register implementation', async () => {
await registry.connect(mimic).register('[email protected]', authorizer.address)
await registry.connect(mimic).register('[email protected]', authorizer.address, false)
})

context('when the implementation is not deprecated', () => {
Expand Down Expand Up @@ -172,8 +172,8 @@ describe('Deployer', () => {

context('when the implementation is registered', () => {
beforeEach('register implementations', async () => {
await registry.connect(mimic).register('[email protected]', smartVault.address)
await registry.connect(mimic).register('[email protected]', PRICE_ORACLE)
await registry.connect(mimic).register('[email protected]', smartVault.address, false)
await registry.connect(mimic).register('[email protected]', PRICE_ORACLE, true)
})

context('when the implementation is not deprecated', () => {
Expand Down Expand Up @@ -292,10 +292,10 @@ describe('Deployer', () => {
const FEE_CONTROLLER = '0x0000000000000000000000000000000000000001'
const WNT = '0x0000000000000000000000000000000000000002'
const smartVaultImpl = await deploy(ARTIFACTS.SMART_VAULT, [registry.address, FEE_CONTROLLER, WNT])
await registry.connect(mimic).register('[email protected]', smartVaultImpl.address)
await registry.connect(mimic).register('[email protected]', smartVaultImpl.address, false)

const PRICE_ORACLE = '0x0000000000000000000000000000000000000004'
await registry.connect(mimic).register('[email protected]', PRICE_ORACLE)
await registry.connect(mimic).register('[email protected]', PRICE_ORACLE, true)

const tx = await deployer.deploySmartVault(namespace, 'smart-vault', {
impl: smartVaultImpl.address,
Expand All @@ -316,7 +316,7 @@ describe('Deployer', () => {

context('when the implementation is registered', () => {
beforeEach('register implementations', async () => {
await registry.connect(mimic).register('[email protected]', task.address)
await registry.connect(mimic).register('[email protected]', task.address, false)
})

context('when the implementation is not deprecated', () => {
Expand Down
19 changes: 13 additions & 6 deletions packages/registry/contracts/Registry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ contract Registry is IRegistry, Ownable {
// List of registered implementations
mapping (address => bool) public override isRegistered;

// List of stateless implementations
mapping (address => bool) public override isStateless;

// List of deprecated implementations
mapping (address => bool) public override isDeprecated;

Expand All @@ -42,19 +45,21 @@ contract Registry is IRegistry, Ownable {
* @dev Creates and registers an implementation
* @param name Name of the implementation
* @param code Code of the implementation to create and register
* @param stateless Whether the new implementation is considered stateless or not
*/
function create(string memory name, bytes memory code) external override onlyOwner {
function create(string memory name, bytes memory code, bool stateless) external override onlyOwner {
address implementation = CREATE3.deploy(keccak256(abi.encode(name)), code, 0);
_register(name, implementation);
_register(name, implementation, stateless);
}

/**
* @dev Registers an implementation
* @param name Name logged for the implementation
* @param implementation Address of the implementation to be registered
* @param stateless Whether the given implementation is considered stateless or not
*/
function register(string memory name, address implementation) external override onlyOwner {
_register(name, implementation);
function register(string memory name, address implementation, bool stateless) external override onlyOwner {
_register(name, implementation, stateless);
}

/**
Expand All @@ -74,12 +79,14 @@ contract Registry is IRegistry, Ownable {
* @dev Registers an implementation
* @param name Name of the implementation
* @param implementation Address of the implementation to be registered
* @param stateless Whether the given implementation is considered stateless or not
*/
function _register(string memory name, address implementation) internal {
function _register(string memory name, address implementation, bool stateless) internal {
require(implementation != address(0), 'REGISTRY_IMPL_ADDRESS_ZERO');
require(!isRegistered[implementation], 'REGISTRY_IMPL_ALREADY_REGISTERED');

isRegistered[implementation] = true;
emit Registered(implementation, name);
isStateless[implementation] = stateless;
emit Registered(implementation, name, stateless);
}
}
14 changes: 11 additions & 3 deletions packages/registry/contracts/interfaces/IRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface IRegistry {
/**
* @dev Emitted every time an implementation is registered
*/
event Registered(address indexed implementation, string name);
event Registered(address indexed implementation, string name, bool stateless);

/**
* @dev Emitted every time an implementation is deprecated
Expand All @@ -38,6 +38,12 @@ interface IRegistry {
*/
function isRegistered(address implementation) external view returns (bool);

/**
* @dev Tells whether an implementation is stateless or not
* @param implementation Address of the implementation being queried
*/
function isStateless(address implementation) external view returns (bool);

/**
* @dev Tells whether an implementation is deprecated
* @param implementation Address of the implementation being queried
Expand All @@ -48,15 +54,17 @@ interface IRegistry {
* @dev Creates and registers an implementation
* @param name Name of the implementation
* @param code Code of the implementation to create and register
* @param stateless Whether the new implementation is considered stateless or not
*/
function create(string memory name, bytes memory code) external;
function create(string memory name, bytes memory code, bool stateless) external;

/**
* @dev Registers an implementation
* @param name Name of the implementation
* @param implementation Address of the implementation to be registered
* @param stateless Whether the given implementation is considered stateless or not
*/
function register(string memory name, address implementation) external;
function register(string memory name, address implementation, bool stateless) external;

/**
* @dev Deprecates an implementation
Expand Down
Loading

0 comments on commit 72571ee

Please sign in to comment.