-
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
Merged
Merged
Base version #1
Changes from 13 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
9731450
Base version
RuslanProgrammer e2f5406
Added BaseFactory
RuslanProgrammer 67283a1
Refactored code
RuslanProgrammer 27a351a
Set CoreProperties upgradeable
RuslanProgrammer d43e490
fixes
RuslanProgrammer 57e7175
refactor logic
FedOken 2f08e6e
updated
RuslanProgrammer f52ec34
removed scripts
RuslanProgrammer 5477fe7
Updated package.json
RuslanProgrammer 9832d66
fixes
RuslanProgrammer fb72f0e
added more tests
RuslanProgrammer 5009610
added config
RuslanProgrammer f624e3e
changed swap params
RuslanProgrammer d829693
changed package-lock.json
RuslanProgrammer 21fc4f5
changed package-lock.json
RuslanProgrammer 60fac6a
changed ci
RuslanProgrammer ecbede2
changed package-lock.json
RuslanProgrammer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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,108 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.20; | ||
|
||
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; | ||
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 calldata poolName_) internal returns (address) { | ||
require(bytes(poolName_).length != 0, "F: poolName_ is empty"); | ||
bytes32 salt_ = _calculatePoolSalt(_msgSender(), poolName_, poolType_); | ||
|
||
address implementation_ = getImplementation(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_}(implementation_, bytes(""))); | ||
|
||
deployedProxies[_msgSender()][poolName_][poolType_] = proxy_; | ||
|
||
emit ProxyDeployed(proxy_, implementation_, poolType_, poolName_); | ||
|
||
return proxy_; | ||
} | ||
|
||
function _predictPoolAddress( | ||
uint8 poolType_, | ||
string calldata poolName_, | ||
address sender_ | ||
) internal view returns (address) { | ||
bytes32 salt_ = _calculatePoolSalt(sender_, poolName_, uint8(poolType_)); | ||
|
||
bytes32 bytecodeHash_ = keccak256( | ||
abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(getImplementation(poolType_), bytes(""))) | ||
); | ||
|
||
return Create2.computeAddress(salt_, bytecodeHash_); | ||
} | ||
|
||
function _calculatePoolSalt( | ||
address sender_, | ||
string calldata poolName_, | ||
uint8 poolType_ | ||
) internal pure returns (bytes32) { | ||
return keccak256(abi.encodePacked(sender_, poolName_, poolType_)); | ||
} | ||
|
||
function _authorizeUpgrade(address) internal view override onlyOwner {} | ||
} |
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
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 {} | ||
} |
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,100 @@ | ||
// 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 setFeeConfig(address feeConfig_) external onlyOwner { | ||
require(feeConfig_ != address(0), "L1F: invalid fee config"); | ||
|
||
feeConfig = feeConfig_; | ||
} | ||
|
||
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( | ||
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()); | ||
} | ||
|
||
function predictAddresses( | ||
string calldata poolName_, | ||
address sender_ | ||
) external view returns (address distribution_, address l1Sender_) { | ||
distribution_ = _predictPoolAddress(uint8(PoolType.DISTRIBUTION), poolName_, sender_); | ||
|
||
l1Sender_ = _predictPoolAddress(uint8(PoolType.L1_SENDER), poolName_, sender_); | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.