-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Base version * Added BaseFactory * Refactored code * Set CoreProperties upgradeable * fixes * refactor logic * updated * removed scripts * Updated package.json * fixes * added more tests * added config * changed swap params * changed package-lock.json * changed package-lock.json * changed ci * changed package-lock.json --------- Co-authored-by: Oleksandr Fedorenko <[email protected]>
- Loading branch information
1 parent
50e0813
commit f645ea0
Showing
72 changed files
with
3,632 additions
and
2,932 deletions.
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
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 { | ||
_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.