-
Notifications
You must be signed in to change notification settings - Fork 6
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
Base version #1
Base version #1
Changes from 9 commits
9731450
e2f5406
67283a1
27a351a
d43e490
57e7175
2f08e6e
f52ec34
5477fe7
9832d66
fb72f0e
5009610
f624e3e
d829693
21fc4f5
60fac6a
ecbede2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.20; | ||
|
||
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; | ||
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; | ||
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; | ||
|
||
import {IFactory} from "./interfaces/IFactory.sol"; | ||
|
||
abstract contract Factory is IFactory, OwnableUpgradeable, PausableUpgradeable, UUPSUpgradeable { | ||
mapping(uint8 => address) internal _implementations; | ||
mapping(bytes32 => bool) private _usedSalts; | ||
|
||
/** | ||
* @dev It is used exclusively for storing information about the detached proxies. | ||
* | ||
* `_msgSender()` -> `poolName` -> `poolType` -> `proxy` | ||
*/ | ||
mapping(address => mapping(string => mapping(uint8 => address))) public deployedProxies; | ||
|
||
function __Factory_init() internal onlyInitializing {} | ||
|
||
/** | ||
* @notice Returns contract to normal state. | ||
*/ | ||
function pause() external onlyOwner { | ||
_pause(); | ||
} | ||
|
||
/** | ||
* @notice Triggers stopped state. | ||
*/ | ||
function unpause() external onlyOwner { | ||
_unpause(); | ||
} | ||
|
||
/** | ||
* @notice The function to set implementation for the specific pool. | ||
* | ||
* @param poolType_ the type of the pool. | ||
* @param implementation_ the implementation the pool will point to. | ||
*/ | ||
function setImplementation(uint8 poolType_, address implementation_) public onlyOwner { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We decided to do it with ERC1967Proxy to have the chance to remove the upgradability |
||
_implementations[poolType_] = implementation_; | ||
} | ||
|
||
/** | ||
* @notice The function to get implementation of the specific pools. | ||
* | ||
* @param poolType_ the type of the pools. | ||
* @return implementation the implementation which the pool points to. | ||
*/ | ||
function getImplementation(uint8 poolType_) public view returns (address) { | ||
return _implementations[poolType_]; | ||
} | ||
|
||
/** | ||
* @notice The function to deploy new `ERC1967Proxy`. | ||
* | ||
* @param poolType_ the type of the pool. | ||
* @param poolName_ the name of the pool. | ||
* @return proxy the proxy address for the `poolType_`. | ||
*/ | ||
function _deploy2(uint8 poolType_, string memory poolName_) internal returns (address) { | ||
require(bytes(poolName_).length != 0, "F: poolName_ is empty"); | ||
bytes32 salt_ = keccak256(abi.encodePacked(_msgSender(), poolName_, poolType_)); | ||
|
||
address implementation_ = _implementations[poolType_]; | ||
require(implementation_ != address(0), "F: implementation not found"); | ||
|
||
require(!_usedSalts[salt_], "F: salt used"); | ||
_usedSalts[salt_] = true; | ||
|
||
address proxy_ = address(new ERC1967Proxy{salt: salt_}(getImplementation(poolType_), bytes(""))); | ||
|
||
deployedProxies[_msgSender()][poolName_][poolType_] = proxy_; | ||
|
||
emit ProxyDeployed(proxy_, implementation_, poolType_, poolName_); | ||
|
||
return proxy_; | ||
} | ||
|
||
function _authorizeUpgrade(address) internal view override onlyOwner {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.20; | ||
|
||
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; | ||
|
||
import {PRECISION} from "@solarity/solidity-lib/utils/Globals.sol"; | ||
|
||
import {IFeeConfig} from "../interfaces/L1/IFeeConfig.sol"; | ||
|
||
contract FeeConfig is IFeeConfig, OwnableUpgradeable, UUPSUpgradeable { | ||
address public treasury; | ||
uint256 public baseFee; | ||
|
||
mapping(address => uint256) public fees; | ||
|
||
function __FeeConfig_init(address treasury_, uint256 baseFee_) external initializer { | ||
__Ownable_init(); | ||
__UUPSUpgradeable_init(); | ||
|
||
treasury = treasury_; | ||
baseFee = baseFee_; | ||
} | ||
|
||
function setFee(address sender_, uint256 fee_) external onlyOwner { | ||
require(fee_ <= PRECISION, "FC: invalid fee"); | ||
|
||
fees[sender_] = fee_; | ||
} | ||
|
||
function setTreasury(address treasury_) external onlyOwner { | ||
require(treasury_ != address(0), "FC: invalid treasury"); | ||
|
||
treasury = treasury_; | ||
} | ||
|
||
function setBaseFee(uint256 baseFee_) external onlyOwner { | ||
require(baseFee_ < PRECISION, "FC: invalid base fee"); | ||
|
||
baseFee = baseFee_; | ||
} | ||
|
||
function getFeeAndTreasury(address sender_) external view returns (uint256, address) { | ||
uint256 fee_ = fees[sender_]; | ||
if (fee_ == 0) { | ||
fee_ = baseFee; | ||
} | ||
|
||
return (fee_, treasury); | ||
} | ||
|
||
function _authorizeUpgrade(address) internal override onlyOwner {} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,85 @@ | ||||||
// SPDX-License-Identifier: MIT | ||||||
pragma solidity ^0.8.20; | ||||||
|
||||||
import {IDistribution} from "../interfaces/L1/IDistribution.sol"; | ||||||
import {IL1Factory} from "../interfaces/L1/IL1Factory.sol"; | ||||||
import {IL1Sender} from "../interfaces/L1/IL1Sender.sol"; | ||||||
import {IOwnable} from "../interfaces/IOwnable.sol"; | ||||||
|
||||||
import {Factory} from "../Factory.sol"; | ||||||
|
||||||
contract L1Factory is IL1Factory, Factory { | ||||||
address public feeConfig; | ||||||
|
||||||
DepositTokenExternalDeps public depositTokenExternalDeps; | ||||||
ArbExternalDeps public arbExternalDeps; | ||||||
LzExternalDeps public lzExternalDeps; | ||||||
|
||||||
constructor() { | ||||||
_disableInitializers(); | ||||||
} | ||||||
|
||||||
function L1Factory_init() external initializer { | ||||||
__Pausable_init(); | ||||||
__Ownable_init(); | ||||||
__UUPSUpgradeable_init(); | ||||||
__Factory_init(); | ||||||
} | ||||||
|
||||||
function setDepositTokenExternalDeps( | ||||||
DepositTokenExternalDeps calldata depositTokenExternalDeps_ | ||||||
) external onlyOwner { | ||||||
require(depositTokenExternalDeps_.token != address(0), "L1F: invalid token"); | ||||||
require(depositTokenExternalDeps_.wToken != address(0), "L1F: invalid wtoken"); | ||||||
|
||||||
depositTokenExternalDeps = depositTokenExternalDeps_; | ||||||
} | ||||||
|
||||||
function setLzExternalDeps(LzExternalDeps calldata lzExternalDeps_) external onlyOwner { | ||||||
require(lzExternalDeps_.endpoint != address(0), "L1F: invalid LZ endpoint"); | ||||||
require(lzExternalDeps_.destinationChainId != 0, "L1F: invalid chain ID"); | ||||||
|
||||||
lzExternalDeps = lzExternalDeps_; | ||||||
} | ||||||
|
||||||
function setArbExternalDeps(ArbExternalDeps calldata arbExternalDeps_) external onlyOwner { | ||||||
require(arbExternalDeps_.endpoint != address(0), "L1F: invalid ARB endpoint"); | ||||||
|
||||||
arbExternalDeps = arbExternalDeps_; | ||||||
} | ||||||
|
||||||
function deploy(L1Params calldata l1Params_) external whenNotPaused { | ||||||
address distributionProxy_ = _deploy2(uint8(PoolType.DISTRIBUTION), l1Params_.protocolName); | ||||||
address l1SenderProxy_ = _deploy2(uint8(PoolType.L1_SENDER), l1Params_.protocolName); | ||||||
|
||||||
IDistribution(distributionProxy_).Distribution_init( | ||||||
depositTokenExternalDeps.token, | ||||||
l1SenderProxy_, | ||||||
feeConfig, | ||||||
l1Params_.poolsInfo | ||||||
); | ||||||
|
||||||
IL1Sender.RewardTokenConfig memory lzConfig_ = IL1Sender.RewardTokenConfig( | ||||||
lzExternalDeps.endpoint, | ||||||
l1Params_.l2MessageReceiver, | ||||||
lzExternalDeps.destinationChainId, | ||||||
lzExternalDeps.zroPaymentAddress, | ||||||
lzExternalDeps.adapterParams | ||||||
); | ||||||
|
||||||
IL1Sender.DepositTokenConfig memory arbConfig = IL1Sender.DepositTokenConfig( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
depositTokenExternalDeps.wToken, | ||||||
arbExternalDeps.endpoint, | ||||||
l1Params_.l2TokenReceiver | ||||||
); | ||||||
|
||||||
IL1Sender(l1SenderProxy_).L1Sender__init(distributionProxy_, lzConfig_, arbConfig); | ||||||
|
||||||
if (l1Params_.isNotUpgradeable) { | ||||||
IDistribution(distributionProxy_).removeUpgradeability(); | ||||||
} | ||||||
|
||||||
IOwnable(distributionProxy_).transferOwnership(_msgSender()); | ||||||
IOwnable(l1SenderProxy_).transferOwnership(_msgSender()); | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add method to precalculate address. It should take deployer as a parameter.