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

fix: modify the asset token in FastSettlementMiddleware #116

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions contracts/fast-settlement/FastSettlementMiddleware.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IOptInService} from "@symbioticfi/core/src/interfaces/service/IOptInService.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";

Check warning on line 12 in contracts/fast-settlement/FastSettlementMiddleware.sol

View workflow job for this annotation

GitHub Actions / Test solidity contracts

imported name ISlasher is not used
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";

import {MapWithTimeData} from "./libraries/MapWithTimeData.sol";
import {ICollateral} from "../interfaces/symbioticfi/ICollateral.sol";
import {ITokenPriceOracle} from "../interfaces/ITokenPriceOracle.sol";
import {IFastSettlementMiddleware} from "../interfaces/IFastSettlementMiddleware.sol";
import {IArbitrator} from "../interfaces/IArbitrator.sol";
Expand Down Expand Up @@ -45,9 +46,9 @@
mapping(uint48 => mapping(address => uint256)) public operatorStakeCache;
EnumerableMapUpgradeable.AddressToUintMap private operators;
EnumerableMapUpgradeable.AddressToUintMap private vaults;
// @notice The risk factor is used to calculate credit for all tokens if it's not set in tokenRiskFactor
/// @notice The risk factor is used to calculate credit for all tokens if it's not set in tokenRiskFactor
uint256 public riskFactor;
// @notice The token risk factor will override the riskFactor if it's set
/// @notice The token risk factor will override the riskFactor if it's set
mapping(address => uint256) public tokenRiskFactor;

error NotOperator();
Expand Down Expand Up @@ -97,30 +98,32 @@
_disableInitializers();
}

/// @notice Initialize the contract
function initialize() external initializer {
__Ownable_init_unchained();
__UUPSUpgradeable_init_unchained();
}

/// @notice Upgrade the contract
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {
// can only call by owner
}

/// @dev Set new risk factor
/// @notice Set new risk factor
function setRiskFactor(uint256 _riskFactor) external onlyOwner {
require(_riskFactor > 0 && _riskFactor <= RISK_FACTOR_DENOMINATOR, "Invalid risk factor");
riskFactor = _riskFactor;
emit RiskFactorUpdate(_riskFactor);
}

/// @dev Set new token risk factor
/// @notice Set new token risk factor
function setTokenRiskFactor(address _token, uint256 _riskFactor) external onlyOwner {
require(_riskFactor > 0 && _riskFactor <= RISK_FACTOR_DENOMINATOR, "Invalid risk factor");
tokenRiskFactor[_token] = _riskFactor;
emit TokenRiskFactorUpdate(_token, _riskFactor);
}

/// @dev Register operator
/// @notice Register operator
function registerOperator(address operator) external onlyOwner {
if (operators.contains(operator)) {
revert OperatorAlreadyRegistered();
Expand All @@ -138,14 +141,17 @@
operators.enable(operator);
}

/// @notice Pause operator
function pauseOperator(address operator) external onlyOwner {
operators.disable(operator);
}

/// @notice Unpause operator
function unpauseOperator(address operator) external onlyOwner {
operators.enable(operator);
}

/// @notice Unregister operator
function unregisterOperator(address operator) external onlyOwner {
(, uint48 disabledTime) = operators.getTimes(operator);

Expand All @@ -156,7 +162,7 @@
operators.remove(operator);
}

/// @dev Register vault
/// @notice Register vault
function registerVault(address vault) external onlyOwner {
if (vaults.contains(vault)) {
revert VaultAlreadyRegistered();
Expand All @@ -181,14 +187,17 @@
vaults.enable(vault);
}

/// @notice Pause vault
function pauseVault(address vault) external onlyOwner {
vaults.disable(vault);
}

/// @notice Unpause vault
function unpauseVault(address vault) external onlyOwner {
vaults.enable(vault);
}

/// @notice Unregister vault
function unregisterVault(address vault) external onlyOwner {
(, uint48 disabledTime) = vaults.getTimes(vault);

Expand All @@ -199,7 +208,12 @@
vaults.remove(vault);
}

/// @dev Send fast sync message to secondary chain via ARBITRATOR
/// @notice Send fast sync message to secondary chain via ARBITRATOR
/// @param _secondaryChainGateway The secondary chain gateway
/// @param _newTotalSyncedPriorityTxs The latest fast sync point
/// @param _syncHash The sync hash
/// @param _expectCollateral The value of the collateral acquired off-chain
/// @param _forwardParams The forward params
function sendFastSyncMessage(
IL1Gateway _secondaryChainGateway,
uint256 _newTotalSyncedPriorityTxs,
Expand All @@ -219,7 +233,7 @@
emit SendFastSyncMessage(_secondaryChainGateway, _newTotalSyncedPriorityTxs, _syncHash, collateral);
}

/// @dev Get available stake value for operator
/// @notice Return the available stake value for the operator at a specific epoch
function getOperatorStakeValue(address operator, uint48 epoch) public view returns (uint256 totalStakeValue) {
if (totalStakeCached[epoch]) {
return operatorStakeCache[epoch][operator];
Expand Down Expand Up @@ -247,25 +261,28 @@
}

address collateralToken = IVault(vault).collateral();
// todo ICollateral(collateralToken).asset()
uint256 tokenPrice = TOKEN_PRICE_ORACLE.getTokenPrice(collateralToken);
address assetToken = ICollateral(collateralToken).asset();
uint256 tokenPrice = TOKEN_PRICE_ORACLE.getTokenPrice(assetToken);
uint256 _riskFactor = getTokenRiskFactor(collateralToken);
uint256 stakeValue = (vaultCollateral * tokenPrice * _riskFactor) / RISK_FACTOR_DENOMINATOR;
totalStakeValue += stakeValue;
}
}

/// @notice Return the available stake value for the operator at the current epoch
function getOperatorStakeCurrentValue(address operator) public view returns (uint256) {
return getOperatorStakeValue(operator, getCurrentEpoch());
}

/// @notice Return the total stake value for all operators at a specific epoch
function getTotalStakeValue(uint48 epoch) public view returns (uint256) {
if (totalStakeCached[epoch]) {
return totalStakeCache[epoch];
}
return _calcTotalStake(epoch);
}

/// @notice Calculate and cache the available stake value
function calcAndCacheStakes(uint48 epoch) public returns (uint256 totalStakeValue) {
uint48 epochStartTs = getEpochStartTs(epoch);

Expand Down Expand Up @@ -296,14 +313,17 @@
totalStakeCache[epoch] = totalStakeValue;
}

/// @notice Return the timestamp of a specific epoch
function getEpochStartTs(uint48 epoch) public view returns (uint48 timestamp) {
return START_TIME + epoch * EPOCH_DURATION;
}

/// @notice Return the epoch of a specific timestamp
function getEpochAtTs(uint48 timestamp) public view returns (uint48 epoch) {
return (timestamp - START_TIME) / EPOCH_DURATION;
}

/// @notice Return the current epoch
function getCurrentEpoch() public view returns (uint48 epoch) {
return getEpochAtTs(uint48(block.timestamp));
}
Expand Down
19 changes: 19 additions & 0 deletions contracts/interfaces/IFastSettlementMiddleware.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,29 @@ pragma solidity ^0.8.0;

import {IL1Gateway} from "./IL1Gateway.sol";
interface IFastSettlementMiddleware {
/**
* @notice Get the available stake value of an operator at a specific epoch
* @param operator Operator address
* @param epoch Epoch
* @return Stake value
*/
function getOperatorStakeValue(address operator, uint48 epoch) external view returns (uint256);

/**
* @notice Get the available stake value for the operator at the current epoch
* @param operator Operator address
* @return Stake value
*/
function getOperatorStakeCurrentValue(address operator) external view returns (uint256);

/**
* @notice Send a fast sync message to the secondary chain
* @param _secondaryChainGateway The secondary chain gateway
* @param _newTotalSyncedPriorityTxs The latest fast sync point
* @param _syncHash The sync hash
* @param _expectCollateral The value of the collateral acquired off-chain
* @param _forwardParams The forward params
*/
function sendFastSyncMessage(
IL1Gateway _secondaryChainGateway,
uint256 _newTotalSyncedPriorityTxs,
Expand Down
91 changes: 91 additions & 0 deletions contracts/interfaces/symbioticfi/ICollateral.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface ICollateral is IERC20 {
/**
* @notice Emitted when debt is issued.
* @param issuer address of the debt's issuer
* @param recipient address that should receive the underlying asset
* @param debtIssued amount of the debt issued
*/
event IssueDebt(address indexed issuer, address indexed recipient, uint256 debtIssued);

/**
* @notice Emitted when debt is repaid.
* @param issuer address of the debt's issuer
* @param recipient address that received the underlying asset
* @param debtRepaid amount of the debt repaid
*/
event RepayDebt(address indexed issuer, address indexed recipient, uint256 debtRepaid);

/**
* @notice Get the collateral's underlying asset.
* @return asset address of the underlying asset
*/
function asset() external view returns (address);

/**
* @notice Get a total amount of repaid debt.
* @return total repaid debt
*/
function totalRepaidDebt() external view returns (uint256);

/**
* @notice Get an amount of repaid debt created by a particular issuer.
* @param issuer address of the debt's issuer
* @return particular issuer's repaid debt
*/
function issuerRepaidDebt(address issuer) external view returns (uint256);

/**
* @notice Get an amount of repaid debt to a particular recipient.
* @param recipient address that received the underlying asset
* @return particular recipient's repaid debt
*/
function recipientRepaidDebt(address recipient) external view returns (uint256);

/**
* @notice Get an amount of repaid debt for a particular issuer-recipient pair.
* @param issuer address of the debt's issuer
* @param recipient address that received the underlying asset
* @return particular pair's repaid debt
*/
function repaidDebt(address issuer, address recipient) external view returns (uint256);

/**
* @notice Get a total amount of debt.
* @return total debt
*/
function totalDebt() external view returns (uint256);

/**
* @notice Get a current debt created by a particular issuer.
* @param issuer address of the debt's issuer
* @return particular issuer's debt
*/
function issuerDebt(address issuer) external view returns (uint256);

/**
* @notice Get a current debt to a particular recipient.
* @param recipient address that should receive the underlying asset
* @return particular recipient's debt
*/
function recipientDebt(address recipient) external view returns (uint256);

/**
* @notice Get a current debt for a particular issuer-recipient pair.
* @param issuer address of the debt's issuer
* @param recipient address that should receive the underlying asset
* @return particular pair's debt
*/
function debt(address issuer, address recipient) external view returns (uint256);

/**
* @notice Burn a given amount of the collateral, and increase a debt of the underlying asset for the caller.
* @param recipient address that should receive the underlying asset
* @param amount amount of the collateral
*/
function issueDebt(address recipient, uint256 amount) external;
}
Loading