Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
RuslanProgrammer committed Apr 25, 2024
1 parent 27a351a commit d43e490
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 168 deletions.
77 changes: 10 additions & 67 deletions contracts/BaseFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,32 @@
pragma solidity ^0.8.20;

import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {ProxyBeacon} from "@solarity/solidity-lib/proxy/beacon/ProxyBeacon.sol";
import {PublicBeaconProxy} from "@solarity/solidity-lib/proxy/beacon/PublicBeaconProxy.sol";
import {Paginator} from "@solarity/solidity-lib/libs/arrays/Paginator.sol";

abstract contract BaseFactory {
using EnumerableSet for EnumerableSet.AddressSet;
using Paginator for EnumerableSet.AddressSet;

mapping(bytes32 => bool) private _usedSalts;

mapping(uint8 => ProxyBeacon) internal _beacons;
mapping(uint8 => EnumerableSet.AddressSet) internal _pools;
mapping(address => mapping(string => mapping(uint8 => address))) public pools;
mapping(uint8 => address) internal _implementations;

/**
* @notice The function to get implementation of the specific pools
* @param poolType_ the type of the pools
* @return address_ the implementation these pools point to
*/
function getImplementation(uint8 poolType_) public view returns (address) {
require(address(_beacons[poolType_]) != address(0), "BaseFactory: this mapping doesn't exist");

return _beacons[poolType_].implementation();
}

/**
* @notice The function to get the BeaconProxy of the specific pools (mostly needed in the factories)
* @param poolType_ type name of the pools
* @return address the BeaconProxy address
*/
function getBeaconProxy(uint8 poolType_) public view returns (address) {
address beacon_ = address(_beacons[poolType_]);
require(_implementations[poolType_] != address(0), "BaseFactory: this mapping doesn't exist");

require(beacon_ != address(0), "BaseFactory: bad PublicBeaconProxy");

return beacon_;
return _implementations[poolType_];
}

/**
* @notice The function to count pools
* @param poolType_ the type of the pools
* @return the number of pools
*/
function countPools(uint8 poolType_) public view returns (uint256) {
return _pools[poolType_].length();
}

/**
* @notice The paginated function to list pools (call `countPools()` to account for pagination)
* @param poolType_ the type of the pools
* @param offset_ the starting index in the address array
* @param limit_ the number of address
* @return pools_ the array of address proxies
*/
function listPools(uint8 poolType_, uint256 offset_, uint256 limit_) public view returns (address[] memory pools_) {
return _pools[poolType_].part(offset_, limit_);
}

function _addPool(uint8 poolType_, address pool_) internal {
_pools[poolType_].add(pool_);
function _addPool(address deployer_, uint8 poolType_, string memory poolName_, address pool_) internal {
pools[deployer_][poolName_][poolType_] = pool_;
}

function _deploy2(uint8 poolType_, string memory poolName_) internal returns (address) {
Expand All @@ -71,37 +36,15 @@ abstract contract BaseFactory {
require(bytes(poolName_).length != 0, "BaseFactory: pool name cannot be empty");
require(!_usedSalts[salt_], "BaseFactory: pool name is already taken");

return address(new PublicBeaconProxy{salt: salt_}(getBeaconProxy(poolType_), bytes("")));
return address(new ERC1967Proxy{salt: salt_}(getImplementation(poolType_), bytes("")));
}

function _updateSalt(string memory poolName_) internal {
_usedSalts[_calculatePoolSalt(tx.origin, poolName_)] = true;
}

/**
* @notice The function that sets pools' implementations. Deploys ProxyBeacons on the first set.
* This function is also used to upgrade pools
* @param poolTypes_ the types that are associated with the pools implementations
* @param newImplementations_ the new implementations of the pools (ProxyBeacons will point to these)
*/
function _setNewImplementations(uint8[] memory poolTypes_, address[] memory newImplementations_) internal {
for (uint256 i = 0; i < poolTypes_.length; i++) {
if (address(_beacons[poolTypes_[i]]) == address(0)) {
_beacons[poolTypes_[i]] = new ProxyBeacon();
}

if (_beacons[poolTypes_[i]].implementation() != newImplementations_[i]) {
_beacons[poolTypes_[i]].upgradeTo(newImplementations_[i]);
}
}
}

function _predictPoolAddress(uint8 poolType_, bytes32 salt_) internal view returns (address) {
bytes32 bytecodeHash_ = keccak256(
abi.encodePacked(type(PublicBeaconProxy).creationCode, abi.encode(getBeaconProxy(poolType_), bytes("")))
);

return Create2.computeAddress(salt_, bytecodeHash_);
function _getImplementation(uint8 poolType_) internal view returns (address) {
return _implementations[poolType_];
}

function _calculatePoolSalt(address deployer_, string memory poolName_) internal pure returns (bytes32) {
Expand Down
11 changes: 2 additions & 9 deletions contracts/L1/BaseFactoryL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,15 @@ abstract contract BaseFactoryL1 is BaseFactory {
IDistribution.Pool[] poolsInfo;
//////
address messageReceiver;
address zroPaymentAddress;
uint16 l2EndpointId;
bytes adapterParams;
//////
address wrappedToken;
address tokenReceiver;
}

event Mor20Deployed(string name, address distribution, address l1Sender);

function _predictPoolAddress(PoolType poolType_, bytes32 poolSalt_) internal view returns (address) {
return _predictPoolAddress(uint8(poolType_), poolSalt_);
}

function _addDistribution(address distribution_) internal {
_pools[uint8(PoolType.DISTRIBUTION)].add(distribution_);
function _addPool(PoolType poolType_, string memory poolName_, address pool_) internal {
_addPool(tx.origin, uint8(poolType_), poolName_, pool_);
}

function _deploy2(PoolType poolType_, string memory name_) internal returns (address) {
Expand Down
58 changes: 0 additions & 58 deletions contracts/L1/CorePropertiesL1.sol

This file was deleted.

27 changes: 11 additions & 16 deletions contracts/L1/Distribution.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {LinearDistributionIntervalDecrease} from "../libs/LinearDistributionInte
import {L1Sender} from "./L1Sender.sol";
import {IDistribution} from "../interfaces/IDistribution.sol";

import {CorePropertiesL1} from "./CorePropertiesL1.sol";
import {FeeParams} from "./FeeParams.sol";

contract Distribution is IDistribution, OwnableUpgradeable {
using SafeERC20 for IERC20;

address public depositToken;
address public l1Sender;
address public feeParams;

// Pool storage
Pool[] public pools;
Expand All @@ -28,8 +29,6 @@ contract Distribution is IDistribution, OwnableUpgradeable {

uint256 public totalDepositedInPublicPools;

CorePropertiesL1 public coreProperties;

/**********************************************************************************************/
/*** Modifiers ***/
/**********************************************************************************************/
Expand Down Expand Up @@ -84,12 +83,9 @@ contract Distribution is IDistribution, OwnableUpgradeable {
Pool storage pool = pools[poolId_];
require(pool.isPublic == pool_.isPublic, "DS: invalid pool type");
if (pool_.payoutStart > block.timestamp) {
require(pool.payoutStart != pool_.payoutStart, "DS: invalid payout start value");
require(pool.payoutStart == pool_.payoutStart, "DS: invalid payout start value");
require(pool.withdrawLockPeriod == pool_.withdrawLockPeriod, "DS: invalid withdrawLockPeriod");
require(
pool.withdrawLockPeriodAfterStake == pool_.withdrawLockPeriodAfterStake,
"DS: invalid withdrawLockPeriodAfterStake"
);
require(pool.withdrawLockPeriodAfterStake == pool_.withdrawLockPeriodAfterStake, "DS: invalid WLPAS value");
}

PoolData storage poolData = poolsData[poolId_];
Expand Down Expand Up @@ -335,11 +331,14 @@ contract Distribution is IDistribution, OwnableUpgradeable {
uint256 overplus_ = overplus();
require(overplus_ > 0, "DS: overplus is zero");

(uint256 feePercent_, address treasuryAddress_) = coreProperties.getFeeAndTreasury(address(this));
uint256 fee_ = _feeAmount(overplus_, feePercent_);
IERC20(depositToken).safeTransfer(treasuryAddress_, fee_);
(uint256 feePercent_, address treasuryAddress_) = FeeParams(feeParams).getFeeAndTreasury(address(this));

overplus_ -= fee_;
uint256 fee_ = (overplus_ * feePercent_) / PRECISION;
if (fee_ != 0) {
IERC20(depositToken).safeTransfer(treasuryAddress_, fee_);

overplus_ -= fee_;
}

IERC20(depositToken).safeTransfer(l1Sender, overplus_);

Expand All @@ -353,8 +352,4 @@ contract Distribution is IDistribution, OwnableUpgradeable {

return bridgeMessageId_;
}

function _feeAmount(uint256 amount_, uint256 feePercent_) internal pure returns (uint256) {
return (amount_ * feePercent_) / PRECISION;
}
}
50 changes: 50 additions & 0 deletions contracts/L1/FeeParams.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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";

contract FeeParams is UUPSUpgradeable, OwnableUpgradeable {
address public treasuryAddress;

uint256 public baseFee;

mapping(address => uint256) public fees;

function __FeeParams_init(address treasuryAddress_, uint256 baseFee_) external initializer {
__Ownable_init();
__UUPSUpgradeable_init();

treasuryAddress = treasuryAddress_;
baseFee = baseFee_;
}

function setFee(address token_, uint256 fee_) external onlyOwner {
require(fee_ < PRECISION, "FeeParams: invalid fee");

fees[token_] = fee_;
}

function setTreasury(address treasuryAddress_) external onlyOwner {
treasuryAddress = treasuryAddress_;
}

function setBaseFee(uint256 baseFee_) external onlyOwner {
require(baseFee_ < PRECISION, "FeeParams: invalid fee");

baseFee = baseFee_;
}

function getFeeAndTreasury(address distributionAddress_) external view returns (uint256, address) {
uint256 fee_ = fees[distributionAddress_];
if (fee_ == 0) {
fee_ = baseFee;
}

return (fee_, treasuryAddress);
}

function _authorizeUpgrade(address) internal override onlyOwner {}
}
44 changes: 26 additions & 18 deletions contracts/L1/Mor20FactoryL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@ pragma solidity ^0.8.20;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

import {BaseFactoryL1} from "./BaseFactoryL1.sol";
import {CorePropertiesL1} from "./CorePropertiesL1.sol";

import {IDistribution} from "../interfaces/IDistribution.sol";
import {IL1Sender} from "../interfaces/IL1Sender.sol";

contract Mor20FactoryL1 is BaseFactoryL1, Ownable {
CorePropertiesL1 public coreProperties;
address public arbitrumGateway;

constructor(address coreProperties_) {
coreProperties = CorePropertiesL1(coreProperties_);
address public lZEnpointAddress; // L1
uint256 public destinationChainId; // arbitrum

address zroPaymentAddress; // LZ
uint16 l2EndpointId;
bytes adapterParams;

constructor(address arbitrumGateway_, address lZEnpointAddress_, uint256 destinationChainId_) {
arbitrumGateway = arbitrumGateway_;
lZEnpointAddress = lZEnpointAddress_;
destinationChainId = destinationChainId_;
}

function deployMor20OnL1(Mor20DeployParams calldata parameters_) external onlyOwner {
(address arbitrumGateway_, address lZEnpointAddress_) = coreProperties.getDeployParams();

address distributionAddress_ = _deploy2(PoolType.DISTRIBUTION, parameters_.name);

address l1SenderAddress_ = _deploy2(PoolType.L1_SENDER, parameters_.name);
Expand All @@ -32,27 +38,29 @@ contract Mor20FactoryL1 is BaseFactoryL1, Ownable {
IL1Sender(l1SenderAddress_).L1Sender__init(
distributionAddress_,
IL1Sender.RewardTokenConfig(
lZEnpointAddress_,
lZEnpointAddress,
parameters_.messageReceiver,
parameters_.l2EndpointId,
parameters_.zroPaymentAddress,
parameters_.adapterParams
l2EndpointId,
zroPaymentAddress,
adapterParams
),
IL1Sender.DepositTokenConfig(parameters_.wrappedToken, arbitrumGateway_, parameters_.tokenReceiver)
IL1Sender.DepositTokenConfig(parameters_.wrappedToken, arbitrumGateway, parameters_.tokenReceiver)
);

_addDistribution(distributionAddress_);

_updateSalt(parameters_.name);
_addPool(PoolType.DISTRIBUTION, parameters_.name, distributionAddress_);
_addPool(PoolType.L1_SENDER, parameters_.name, distributionAddress_);

emit Mor20Deployed(parameters_.name, distributionAddress_, l1SenderAddress_);
}

function setNewImplementations(
uint8[] memory poolTypes_,
address[] calldata newImplementations_
function setDeployParams(
address arbitrumGateway_,
address lZEnpointAddress_,
uint256 destinationChainId_
) external onlyOwner {
_setNewImplementations(poolTypes_, newImplementations_);
arbitrumGateway = arbitrumGateway_;
lZEnpointAddress = lZEnpointAddress_;
destinationChainId = destinationChainId_;
}

function predictMor20Address(
Expand Down

0 comments on commit d43e490

Please sign in to comment.