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

Feat/shperex #169

Merged
merged 13 commits into from
Oct 16, 2023
35 changes: 35 additions & 0 deletions contracts/core/ContractsRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import "@solarity/solidity-lib/contracts-registry/presets/OwnableContractsRegist

import "../interfaces/core/IContractsRegistry.sol";

import "../proxy/ProtectedTransparentProxy.sol";

contract ContractsRegistry is IContractsRegistry, OwnableContractsRegistry, UUPSUpgradeable {
string public constant USER_REGISTRY_NAME = "USER_REGISTRY";

Expand Down Expand Up @@ -74,5 +76,38 @@ contract ContractsRegistry is IContractsRegistry, OwnableContractsRegistry, UUPS
return getContract(DEXE_EXPERT_NFT_NAME);
}

function setSphereXEngine(address sphereXEngine) external onlyOwner {
_setSphereXEngine(USER_REGISTRY_NAME, sphereXEngine);
_setSphereXEngine(POOL_FACTORY_NAME, sphereXEngine);
_setSphereXEngine(POOL_REGISTRY_NAME, sphereXEngine);
_setSphereXEngine(DEXE_EXPERT_NFT_NAME, sphereXEngine);
_setSphereXEngine(PRICE_FEED_NAME, sphereXEngine);
_setSphereXEngine(CORE_PROPERTIES_NAME, sphereXEngine);
}

function _setSphereXEngine(string memory contractName, address sphereXEngine) internal {
ProtectedTransparentProxy(payable(getContract(contractName))).changeSphereXEngine(
sphereXEngine
);
}

function _deployProxy(
address contractAddress,
address admin,
bytes memory data
) internal override returns (address) {
return
address(
new ProtectedTransparentProxy(
msg.sender,
address(this),
address(0),
contractAddress,
admin,
data
)
);
}

function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
}
47 changes: 47 additions & 0 deletions contracts/factory/PoolFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import "../gov/validators/GovValidators.sol";
import "../core/CoreProperties.sol";
import {PoolRegistry} from "./PoolRegistry.sol";

import "../proxy/ProtectedPublicBeaconProxy.sol";

import "../libs/factory/GovTokenDeployer.sol";

import "../core/Globals.sol";
Expand Down Expand Up @@ -249,6 +251,51 @@ contract PoolFactory is IPoolFactory, AbstractPoolFactory {
_injectDependencies(address(_poolRegistry), proxy);
}

function _deploy(
address poolRegistry,
string memory poolType
) internal override returns (address) {
return
address(
new ProtectedPublicBeaconProxy(
AbstractPoolContractsRegistry(poolRegistry).getProxyBeacon(poolType),
bytes("")
)
);
}

function _deploy2(
address poolRegistry,
string memory poolType,
bytes32 salt
) internal override returns (address) {
return
address(
new ProtectedPublicBeaconProxy{salt: salt}(
AbstractPoolContractsRegistry(poolRegistry).getProxyBeacon(poolType),
bytes("")
)
);
}

function _predictPoolAddress(
address poolRegistry,
string memory poolType,
bytes32 salt
) internal view override returns (address) {
bytes32 bytecodeHash = keccak256(
abi.encodePacked(
type(ProtectedPublicBeaconProxy).creationCode,
abi.encode(
AbstractPoolContractsRegistry(poolRegistry).getProxyBeacon(poolType),
bytes("")
)
)
);

return Create2.computeAddress(salt, bytecodeHash);
}

function _predictPoolAddress(
string memory poolType,
bytes32 salt
Expand Down
23 changes: 23 additions & 0 deletions contracts/factory/PoolRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import "@solarity/solidity-lib/libs/arrays/Paginator.sol";
import "../interfaces/factory/IPoolRegistry.sol";
import "../interfaces/core/IContractsRegistry.sol";

import "../proxy/PoolBeacon.sol";

contract PoolRegistry is IPoolRegistry, OwnablePoolContractsRegistry {
using EnumerableSet for EnumerableSet.AddressSet;
using Paginator for EnumerableSet.AddressSet;
Expand Down Expand Up @@ -48,11 +50,32 @@ contract PoolRegistry is IPoolRegistry, OwnablePoolContractsRegistry {
_addProxyPool(name, poolAddress);
}

function setSphereXEngine(address sphereXEngine) external onlyOwner {
_setSphereXEngine(GOV_POOL_NAME, sphereXEngine);
_setSphereXEngine(SETTINGS_NAME, sphereXEngine);
_setSphereXEngine(VALIDATORS_NAME, sphereXEngine);
_setSphereXEngine(USER_KEEPER_NAME, sphereXEngine);
_setSphereXEngine(DISTRIBUTION_PROPOSAL_NAME, sphereXEngine);
_setSphereXEngine(TOKEN_SALE_PROPOSAL_NAME, sphereXEngine);
_setSphereXEngine(EXPERT_NFT_NAME, sphereXEngine);
_setSphereXEngine(NFT_MULTIPLIER_NAME, sphereXEngine);
_setSphereXEngine(LINEAR_POWER_NAME, sphereXEngine);
_setSphereXEngine(POLYNOMIAL_POWER_NAME, sphereXEngine);
}

function isGovPool(address potentialPool) external view override returns (bool) {
return isPool(GOV_POOL_NAME, potentialPool);
}

function _setSphereXEngine(string memory poolName, address sphereXEngine) internal {
PoolBeacon(getProxyBeacon(poolName)).changeSphereXEngine(sphereXEngine);
}

function _onlyPoolFactory() internal view {
require(_poolFactory == msg.sender, "PoolRegistry: Caller is not a factory");
}

function _deployProxyBeacon() internal override returns (address) {
return address(new PoolBeacon(msg.sender, address(this), address(0)));
}
}
4 changes: 4 additions & 0 deletions contracts/interfaces/core/IContractsRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ pragma solidity ^0.8.20;
* contracts, provide upgradeability mechanism and dependency injection mechanism.
*/
interface IContractsRegistry {
/// @notice The function to set the SphereX engine to all the contracts handled by the registry
/// @param sphereXEngine the address of the SphereX engine
function setSphereXEngine(address sphereXEngine) external;

/// @notice Used in dependency injection mechanism
/// @return UserRegistry contract address
function getUserRegistryContract() external view returns (address);
Expand Down
4 changes: 4 additions & 0 deletions contracts/interfaces/factory/IPoolRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ interface IPoolRegistry {
/// @param poolAddress the address of the pool to add
function addProxyPool(string calldata name, address poolAddress) external;

/// @notice The function to set the SphereX engine to all the contracts handled by the registry
/// @param sphereXEngine the address of the SphereX engine
function setSphereXEngine(address sphereXEngine) external;

/// @notice The function to check if the given address is a valid GovPool
/// @param potentialPool the address to inspect
/// @return true if the address is a GovPool, false otherwise
Expand Down
27 changes: 27 additions & 0 deletions contracts/mock/gov/GovPoolMigration.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@spherex-xyz/contracts/src/SphereXProtectedBase.sol";

contract GovPoolMigration {
address internal immutable DEPLOYER;

constructor() {
DEPLOYER = msg.sender;
}

modifier onlyDeployer() {
_onlyDeployer();
_;
}

function acceptSphereXAdmins(address[] calldata sphereXProxies) external onlyDeployer {
for (uint256 i = 0; i < sphereXProxies.length; ++i) {
SphereXProtectedBase(sphereXProxies[i]).acceptSphereXAdminRole();
}
}

function _onlyDeployer() internal {
require(msg.sender == DEPLOYER, "Gov: caller is not a deployer");
}
}
21 changes: 21 additions & 0 deletions contracts/proxy/PoolBeacon.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@spherex-xyz/contracts/src/SphereXProxyStorage.sol";
import "@spherex-xyz/contracts/src/ProtectedProxies/ISphereXBeacon.sol";

import "@solarity/solidity-lib/contracts-registry/pools/proxy/ProxyBeacon.sol";

contract PoolBeacon is ISphereXBeacon, SphereXProxyBase, ProxyBeacon {
constructor(
address sphereXAdmin,
address sphereXOperator,
address sphereXEngine
) SphereXProxyBase(sphereXAdmin, sphereXOperator, sphereXEngine) {}

function protectedImplementation(
bytes4 selector
) external view returns (address, address, bool) {
return (implementation(), sphereXEngine(), isProtectedFuncSig(selector));
}
}
14 changes: 14 additions & 0 deletions contracts/proxy/ProtectedPublicBeaconProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/proxy/beacon/IBeacon.sol";

import "@spherex-xyz/contracts/src/ProtectedProxies/ProtectedBeaconProxy.sol";

contract ProtectedPublicBeaconProxy is ProtectedBeaconProxy {
constructor(address beacon, bytes memory data) ProtectedBeaconProxy(beacon, data) {}

function implementation() external view returns (address) {
return IBeacon(_getBeacon()).implementation();
}
}
30 changes: 30 additions & 0 deletions contracts/proxy/ProtectedTransparentProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

import "@spherex-xyz/contracts/src/SphereXProtectedProxy.sol";

contract ProtectedTransparentProxy is SphereXProtectedProxy, TransparentUpgradeableProxy {
constructor(
address sphereXAdmin,
address sphereXOperator,
address sphereXEngine,
address implementation,
address proxyAdmin,
bytes memory data
)
SphereXProtectedProxy(sphereXAdmin, sphereXOperator, sphereXEngine)
TransparentUpgradeableProxy(implementation, proxyAdmin, data)
{}

function _fallback() internal virtual override(Proxy, TransparentUpgradeableProxy) {
TransparentUpgradeableProxy._fallback();
}

function _delegate(
address implementation
) internal virtual override(Proxy, SphereXProtectedProxy) {
SphereXProtectedProxy._delegate(implementation);
}
}
58 changes: 58 additions & 0 deletions deploy/95_DEXEDAOSphereXAdmin.migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const Proxy = artifacts.require("ERC1967Proxy");
const ContractsRegistry = artifacts.require("ContractsRegistry");
const PoolRegistry = artifacts.require("PoolRegistry");
const SphereXProtectedBase = artifacts.require("ProtectedTransparentProxy");
const GovPool = artifacts.require("GovPool");
const GovPoolMigration = artifacts.require("GovPoolMigration");

module.exports = async (deployer, logger) => {
const contractsRegistry = await ContractsRegistry.at((await Proxy.deployed()).address);

const poolRegistry = await PoolRegistry.at(await contractsRegistry.getPoolRegistryContract());

const proxies = [
["PoolRegistry", poolRegistry.address],
["UserRegistry", await contractsRegistry.getUserRegistryContract()],
["PoolFactory", await contractsRegistry.getPoolFactoryContract()],
["DexeExpertNft", await contractsRegistry.getDexeExpertNftContract()],
["PriceFeed", await contractsRegistry.getPriceFeedContract()],
["CoreProperties", await contractsRegistry.getCorePropertiesContract()],
["GovPool", await poolRegistry.getProxyBeacon(await poolRegistry.GOV_POOL_NAME())],
["GovSettings", await poolRegistry.getProxyBeacon(await poolRegistry.SETTINGS_NAME())],
["GovValidators", await poolRegistry.getProxyBeacon(await poolRegistry.VALIDATORS_NAME())],
["GovUserKeeper", await poolRegistry.getProxyBeacon(await poolRegistry.USER_KEEPER_NAME())],
["DistributionProposal", await poolRegistry.getProxyBeacon(await poolRegistry.DISTRIBUTION_PROPOSAL_NAME())],
["TokenSaleProposal", await poolRegistry.getProxyBeacon(await poolRegistry.TOKEN_SALE_PROPOSAL_NAME())],
["ExpertNft", await poolRegistry.getProxyBeacon(await poolRegistry.EXPERT_NFT_NAME())],
["NftMultiplier", await poolRegistry.getProxyBeacon(await poolRegistry.NFT_MULTIPLIER_NAME())],
["LinearPower", await poolRegistry.getProxyBeacon(await poolRegistry.LINEAR_POWER_NAME())],
["PolynomialPower", await poolRegistry.getProxyBeacon(await poolRegistry.POLYNOMIAL_POWER_NAME())],
];

logger.logContracts(...proxies);

const govPoolImplementation = await poolRegistry.getImplementation(await poolRegistry.GOV_POOL_NAME());
const govPoolMigration = (await deployer.deploy(GovPoolMigration)).address;

logger.logTransaction(
await poolRegistry.setNewImplementations([await poolRegistry.GOV_POOL_NAME()], [govPoolMigration]),
"Setting a default GovPool implementation"
);

for (const [contractName, proxy] of proxies) {
logger.logTransaction(
await (await SphereXProtectedBase.at(proxy)).transferSphereXAdminRole(deployer.dexeDaoAddress),
`Transferring a SphereX admin role for the ${contractName} proxy`
);
}

logger.logTransaction(
await (await GovPoolMigration.at(deployer.dexeDaoAddress)).acceptSphereXAdmins(proxies.map((e) => e[1])),
"Accepting SphereX admin roles"
);

logger.logTransaction(
await poolRegistry.setNewImplementations([await poolRegistry.GOV_POOL_NAME()], [govPoolImplementation]),
"Setting a default GovPool implementation"
);
};
15 changes: 15 additions & 0 deletions docs/core/IContractsRegistry.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ the other contracts used by the protocol. Its purpose is to keep track of the pr
contracts, provide upgradeability mechanism and dependency injection mechanism.
## Functions info

### setSphereXEngine (0x44a63d1b)

```solidity
function setSphereXEngine(address sphereXEngine) external
```

The function to set the SphereX engine to all the contracts handled by the registry


Parameters:

| Name | Type | Description |
| :------------ | :------ | :-------------------------------- |
| sphereXEngine | address | the address of the SphereX engine |

### getUserRegistryContract (0x435403b4)

```solidity
Expand Down
15 changes: 15 additions & 0 deletions docs/factory/IPoolRegistry.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ Parameters:
| name | string | the type of the pool |
| poolAddress | address | the address of the pool to add |

### setSphereXEngine (0x44a63d1b)

```solidity
function setSphereXEngine(address sphereXEngine) external
```

The function to set the SphereX engine to all the contracts handled by the registry


Parameters:

| Name | Type | Description |
| :------------ | :------ | :-------------------------------- |
| sphereXEngine | address | the address of the SphereX engine |

### isGovPool (0x9e475551)

```solidity
Expand Down
Loading