ETH Price: $2,061.87 (-0.00%)
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FeeCalculatorProd

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;

import "./FeeCalculatorBase.sol";

contract FeeCalculatorProd is FeeCalculatorBase {
  function getOblsContract() public pure override returns (IOBLS) {
    return IOBLS(0xF4c3E87e2bBB7cbe9Fe2f98ae061362B95b4d57d);
  }

  function getRewardPerTask() public pure override returns (uint256) {
    return 50e18;
  }

  function shouldSkipAttester(
    uint256 attesterId
  ) public pure override returns (bool) {
    return attesterId < 6;
  }
}

// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;

import "./IFeeCalculator.sol";
import "../IOBLS.sol";

error CalculateBaseRewardFeesBlocked();
error MaxRewardExceeded(uint256 totalReward);

/// @dev Environment-specific contracts must implement getter functions
abstract contract FeeCalculatorBase is IFeeCalculator {
  /// @notice Returns the OBLs contract
  function getOblsContract() public view virtual returns (IOBLS);

  /// @notice Returns the reward amount per task
  function getRewardPerTask() public view virtual returns (uint256);

  /// @notice Checks if the given attester should be skipped from reward calculation.
  function shouldSkipAttester(
    uint256 attesterId
  ) public view virtual returns (bool);

  /// @dev This function should never be called since base reward fees are disabled
  function calculateBaseRewardFees(
    FeeCalculatorData calldata
  ) external pure returns (uint256, uint256, uint256) {
    revert CalculateBaseRewardFeesBlocked();
  }

  /// @notice Calculates fees per attester based on their voting power.
  /// @param _feeCalculatorData Struct containing attester IDs.
  /// @return feesPerId Array of FeePerId containing attester IDs and their allocated reward.
  function calculateFeesPerId(
    FeeCalculatorData calldata _feeCalculatorData
  ) external view returns (FeePerId[] memory feesPerId) {
    uint256 attestersLen = _feeCalculatorData.attestersIds.length;
    uint256 rewardsCount = 0;

    for (uint256 i = 0; i < attestersLen; ) {
      uint256 attesterId = _feeCalculatorData.attestersIds[i];
      if (!shouldSkipAttester(attesterId)) {
        unchecked {
          rewardsCount++;
        }
      }
      unchecked {
        i++;
      }
    }

    FeePerId[] memory result = new FeePerId[](rewardsCount);
    IOBLS oblsContract = getOblsContract();
    uint256 rewardPerTask = getRewardPerTask();
    uint256 totalVotingPower = oblsContract.totalVotingPower();
    uint256 resultIdx = 0;
    uint256 totalReward = 0;

    for (uint256 i = 0; i < attestersLen; ) {
      uint256 attesterId = _feeCalculatorData.attestersIds[i];
      unchecked {
        i++;
      }
      if (shouldSkipAttester(attesterId)) {
        continue;
      }
      uint256 attesterVotingPower = oblsContract.votingPower(attesterId);
      uint256 reward = (rewardPerTask * attesterVotingPower) / totalVotingPower;
      totalReward += reward;
      result[resultIdx] = FeePerId(attesterId, reward);
      unchecked {
        resultIdx++;
      }
    }
    if (totalReward > rewardPerTask) {
      revert MaxRewardExceeded(totalReward);
    }
    return result;
  }

  /// @notice Returns whether this contract calculates base reward fees (always false).
  function isBaseRewardFee() external pure override returns (bool) {
    return false;
  }
}

// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;

/*______     __      __                              __      __ 
 /      \   /  |    /  |                            /  |    /  |
/$$$$$$  | _$$ |_   $$ |____    ______   _______   _$$ |_   $$/   _______ 
$$ |  $$ |/ $$   |  $$      \  /      \ /       \ / $$   |  /  | /       |
$$ |  $$ |$$$$$$/   $$$$$$$  |/$$$$$$  |$$$$$$$  |$$$$$$/   $$ |/$$$$$$$/ 
$$ |  $$ |  $$ | __ $$ |  $$ |$$    $$ |$$ |  $$ |  $$ | __ $$ |$$ |
$$ \__$$ |  $$ |/  |$$ |  $$ |$$$$$$$$/ $$ |  $$ |  $$ |/  |$$ |$$ \_____ 
$$    $$/   $$  $$/ $$ |  $$ |$$       |$$ |  $$ |  $$  $$/ $$ |$$       |
 $$$$$$/     $$$$/  $$/   $$/  $$$$$$$/ $$/   $$/    $$$$/  $$/  $$$$$$$/
*/

/**
 * @author Othentic Labs LTD.
 * @notice Terms of Service: https://www.othentic.xyz/terms-of-service
 * @notice Depending on the application, it may be necessary to add reentrancy gaurds to hooks
 */

import {IAttestationCenter} from "../IAttestationCenter.sol";

interface IFeeCalculator {
  struct FeeCalculatorData {
    IAttestationCenter.TaskInfo data;
    uint256 aggregatorId;
    uint256 performerId;
    uint256[] attestersIds;
    bool isApproved;
  }

  struct FeePerId {
    uint256 index;
    uint256 fee;
  }

  function calculateBaseRewardFees(
    FeeCalculatorData calldata _feeCalculatorData
  )
    external
    returns (
      uint256 baseRewardFeeForAttesters,
      uint256 baseRewardFeeForAggregator,
      uint256 baseRewardFeeForPerformer
    );
  function calculateFeesPerId(
    FeeCalculatorData calldata _feeCalculatorData
  ) external returns (FeePerId[] memory feesPerId);
  function isBaseRewardFee() external pure returns (bool);
}

// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;
/**
 * @author Othentic Labs LTD.
 * @notice Terms of Service: https://www.othentic.xyz/terms-of-service
 */
import {IAvsLogic} from "./IAvsLogic.sol";
import "./IOBLS.sol";

interface IAttestationCenter {
  enum OperatorStatus {
    INACTIVE,
    ACTIVE
  }

  enum PaymentStatus {
    REDEEMED,
    COMMITTED,
    CHALLENGED
  }

  struct PaymentDetails {
    address operator;
    uint256 lastPaidTaskNumber;
    uint256 feeToClaim;
    PaymentStatus paymentStatus;
  }

  struct PaymentRequestMessage {
    address operator;
    uint256 feeToClaim;
  }

  struct TaskInfo {
    string proofOfTask;
    bytes data;
    address taskPerformer;
    uint16 taskDefinitionId;
  }
  event OperatorRegisteredToNetwork(address operator, uint256 shares);
  event OperatorUnregisteredFromNetwork(uint256 operatorId);
  event OperatorSharesModified(address operator, uint256 shares);
  event PaymentRequested(
    address operator,
    uint256 lastPaidTaskNumber,
    uint256 feeToClaim
  );
  event PaymentsRequested(
    PaymentRequestMessage[] operators,
    uint256 lastPaidTaskNumber
  );
  event ClearPaymentRejected(
    address operator,
    uint256 requestedTaskNumber,
    uint256 requestedAmountClaimed
  );
  event TaskSubmited(
    address operator,
    uint32 taskNumber,
    string proofOfTask,
    bytes data,
    uint16 taskDefinitionId
  );
  event TaskRejected(
    address operator,
    uint32 taskNumber,
    string proofOfTask,
    bytes data,
    uint16 taskDefinitionId
  );
  event SetAvsLogic(address avsLogic);
  event SetAvsGovernanceMultisig(address newAvsGovernanceMultisig);
  event SetObls(address obls);
  event SetMessageHandler(address newMessageHandler);
  event RewardAccumulated(
    uint256 indexed _operatorId,
    uint256 _baseRewardFeeForOperator,
    uint32 indexed _taskNumber
  );
  event SetFeeCalculator(address feeCalculator);

  error InvalidOperatorId();
  error InvalidOperatorsForPayment();
  error PaymentReedemed();
  error PaymentClaimed();
  error InvalidPaymentClaim();
  error MessageAlreadySigned();
  error InactiveTaskPerformer();
  error InactiveAggregator();
  error InvalidTaskDefinition();
  error OperatorNotRegistered();
  error InvalidPerformerSignature();

  function taskNumber() external view returns (uint32);

  function baseRewardFee() external view returns (uint256);

  function numOfOperators() external view returns (uint256);

  function getOperatorPaymentDetail(
    uint256 _operatorId
  ) external view returns (PaymentDetails memory);

  function operatorsIdsByAddress(
    address _operator
  ) external view returns (uint256);

  function avsLogic() external view returns (IAvsLogic);

  function obls() external view returns (IOBLS);

  function submitTask(
    TaskInfo calldata _taskInfo,
    bool _isApproved,
    bytes calldata _tpSignature,
    uint256[2] calldata _taSignature,
    uint256[] calldata _attestersIds
  ) external;

  function requestPayment(uint256 _operatorId) external;

  function requestBatchPayment() external;

  function registerToNetwork(
    address _operator,
    uint256 _numOfShares,
    uint256[4] memory _blsKey
  ) external;

  function unRegisterOperatorFromNetwork(address _operator) external;

  function modifyNumOfShares(
    uint256 _operatorId,
    uint256 _numOfShares
  ) external;

  function clearPayment(
    address _operator,
    uint256 _lastPaidTaskNumber,
    uint256 _amountClaimed
  ) external;

  function clearBatchPayment(
    PaymentRequestMessage[] memory _operators,
    uint256 _lastPaidTaskNumber
  ) external;

  function transferAvsGovernanceMultisig(
    address _newAvsGovernanceMultisig
  ) external;

  function setAvsLogic(IAvsLogic _avsLogic) external;
}

// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;

/*______     __      __                              __      __ 
 /      \   /  |    /  |                            /  |    /  |
/$$$$$$  | _$$ |_   $$ |____    ______   _______   _$$ |_   $$/   _______ 
$$ |  $$ |/ $$   |  $$      \  /      \ /       \ / $$   |  /  | /       |
$$ |  $$ |$$$$$$/   $$$$$$$  |/$$$$$$  |$$$$$$$  |$$$$$$/   $$ |/$$$$$$$/ 
$$ |  $$ |  $$ | __ $$ |  $$ |$$    $$ |$$ |  $$ |  $$ | __ $$ |$$ |
$$ \__$$ |  $$ |/  |$$ |  $$ |$$$$$$$$/ $$ |  $$ |  $$ |/  |$$ |$$ \_____ 
$$    $$/   $$  $$/ $$ |  $$ |$$       |$$ |  $$ |  $$  $$/ $$ |$$       |
 $$$$$$/     $$$$/  $$/   $$/  $$$$$$$/ $$/   $$/    $$$$/  $$/  $$$$$$$/
*/
import {IAttestationCenter} from "./IAttestationCenter.sol";
/**
 * @author Othentic Labs LTD.
 * @notice Terms of Service: https://www.othentic.xyz/terms-of-service
 * @notice Depending on the application, it may be necessary to add reentrancy gaurds to hooks
 */
interface IAvsLogic {
  function afterTaskSubmission(
    IAttestationCenter.TaskInfo calldata _taskInfo,
    bool _isApproved,
    bytes calldata _tpSignature,
    uint256[2] calldata _taSignature,
    uint256[] calldata _attestersIds
  ) external;

  function beforeTaskSubmission(
    IAttestationCenter.TaskInfo calldata _taskInfo,
    bool _isApproved,
    bytes calldata _tpSignature,
    uint256[2] calldata _taSignature,
    uint256[] calldata _attestersIds
  ) external;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IOBLS {
  function totalVotingPower() external view returns (uint256);
  function votingPower(uint256 _index) external view returns (uint256);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"CalculateBaseRewardFeesBlocked","type":"error"},{"inputs":[{"internalType":"uint256","name":"totalReward","type":"uint256"}],"name":"MaxRewardExceeded","type":"error"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"proofOfTask","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"taskPerformer","type":"address"},{"internalType":"uint16","name":"taskDefinitionId","type":"uint16"}],"internalType":"struct IAttestationCenter.TaskInfo","name":"data","type":"tuple"},{"internalType":"uint256","name":"aggregatorId","type":"uint256"},{"internalType":"uint256","name":"performerId","type":"uint256"},{"internalType":"uint256[]","name":"attestersIds","type":"uint256[]"},{"internalType":"bool","name":"isApproved","type":"bool"}],"internalType":"struct IFeeCalculator.FeeCalculatorData","name":"","type":"tuple"}],"name":"calculateBaseRewardFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"proofOfTask","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"taskPerformer","type":"address"},{"internalType":"uint16","name":"taskDefinitionId","type":"uint16"}],"internalType":"struct IAttestationCenter.TaskInfo","name":"data","type":"tuple"},{"internalType":"uint256","name":"aggregatorId","type":"uint256"},{"internalType":"uint256","name":"performerId","type":"uint256"},{"internalType":"uint256[]","name":"attestersIds","type":"uint256[]"},{"internalType":"bool","name":"isApproved","type":"bool"}],"internalType":"struct IFeeCalculator.FeeCalculatorData","name":"_feeCalculatorData","type":"tuple"}],"name":"calculateFeesPerId","outputs":[{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"internalType":"struct IFeeCalculator.FeePerId[]","name":"feesPerId","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOblsContract","outputs":[{"internalType":"contract IOBLS","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getRewardPerTask","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isBaseRewardFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"attesterId","type":"uint256"}],"name":"shouldSkipAttester","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b506106c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b34ac4a511610050578063b34ac4a5146100ee578063d005a4f614610105578063debd07df1461010c57600080fd5b806312ee8d771461007757806336684b67146100a057806355a85664146100c0575b600080fd5b61008b610085366004610465565b60061190565b60405190151581526020015b60405180910390f35b6100b36100ae36600461047e565b61012e565b60405161009791906104c0565b6100d36100ce36600461047e565b61042e565b60408051938452602084019290925290820152606001610097565b6040516802b5e3af16b18800008152602001610097565b600061008b565b60405173f4c3e87e2bbb7cbe9fe2f98ae061362b95b4d57d8152602001610097565b6060600061013e8383018461050f565b905090506000805b8281101561019457600061015d606087018761050f565b8381811061016d5761016d61057e565b9050602002013590506101808160061190565b61018b576001909201915b50600101610146565b5060008167ffffffffffffffff8111156101b0576101b06105ad565b6040519080825280602002602001820160405280156101f557816020015b60408051808201909152600080825260208201528152602001906001900390816101ce5790505b509050600073f4c3e87e2bbb7cbe9fe2f98ae061362b95b4d57d905060006802b5e3af16b1880000905060008273ffffffffffffffffffffffffffffffffffffffff1663671b37936040518163ffffffff1660e01b8152600401602060405180830381865afa15801561026c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029091906105dc565b905060008060005b888110156103de5760006102af60608d018d61050f565b838181106102bf576102bf61057e565b90506020020135905081806001019250506102da8160061190565b156102e55750610298565b6040517f72c4a9270000000000000000000000000000000000000000000000000000000081526004810182905260009073ffffffffffffffffffffffffffffffffffffffff8916906372c4a92790602401602060405180830381865afa158015610353573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037791906105dc565b9050600086610386838a610624565b6103909190610641565b905061039c818661067c565b94506040518060400160405280848152602001828152508a87815181106103c5576103c561057e565b6020908102919091010152505060019093019250610298565b5083811115610420576040517fa23de7940000000000000000000000000000000000000000000000000000000081526004810182905260240160405180910390fd5b509398975050505050505050565b60008060006040517fabf5081900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006020828403121561047757600080fd5b5035919050565b60006020828403121561049057600080fd5b813567ffffffffffffffff8111156104a757600080fd5b820160a081850312156104b957600080fd5b9392505050565b602080825282518282018190526000919060409081850190868401855b82811015610502578151805185528601518685015292840192908501906001016104dd565b5091979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261054457600080fd5b83018035915067ffffffffffffffff82111561055f57600080fd5b6020019150600581901b360382131561057757600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105ee57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761063b5761063b6105f5565b92915050565b600082610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082018082111561063b5761063b6105f556fea26469706673582212203173ed46160404f3b14f4fd0083f41a6dc2af18a770895f9f6b979ec34adfdaf64736f6c63430008110033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b34ac4a511610050578063b34ac4a5146100ee578063d005a4f614610105578063debd07df1461010c57600080fd5b806312ee8d771461007757806336684b67146100a057806355a85664146100c0575b600080fd5b61008b610085366004610465565b60061190565b60405190151581526020015b60405180910390f35b6100b36100ae36600461047e565b61012e565b60405161009791906104c0565b6100d36100ce36600461047e565b61042e565b60408051938452602084019290925290820152606001610097565b6040516802b5e3af16b18800008152602001610097565b600061008b565b60405173f4c3e87e2bbb7cbe9fe2f98ae061362b95b4d57d8152602001610097565b6060600061013e8383018461050f565b905090506000805b8281101561019457600061015d606087018761050f565b8381811061016d5761016d61057e565b9050602002013590506101808160061190565b61018b576001909201915b50600101610146565b5060008167ffffffffffffffff8111156101b0576101b06105ad565b6040519080825280602002602001820160405280156101f557816020015b60408051808201909152600080825260208201528152602001906001900390816101ce5790505b509050600073f4c3e87e2bbb7cbe9fe2f98ae061362b95b4d57d905060006802b5e3af16b1880000905060008273ffffffffffffffffffffffffffffffffffffffff1663671b37936040518163ffffffff1660e01b8152600401602060405180830381865afa15801561026c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029091906105dc565b905060008060005b888110156103de5760006102af60608d018d61050f565b838181106102bf576102bf61057e565b90506020020135905081806001019250506102da8160061190565b156102e55750610298565b6040517f72c4a9270000000000000000000000000000000000000000000000000000000081526004810182905260009073ffffffffffffffffffffffffffffffffffffffff8916906372c4a92790602401602060405180830381865afa158015610353573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037791906105dc565b9050600086610386838a610624565b6103909190610641565b905061039c818661067c565b94506040518060400160405280848152602001828152508a87815181106103c5576103c561057e565b6020908102919091010152505060019093019250610298565b5083811115610420576040517fa23de7940000000000000000000000000000000000000000000000000000000081526004810182905260240160405180910390fd5b509398975050505050505050565b60008060006040517fabf5081900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006020828403121561047757600080fd5b5035919050565b60006020828403121561049057600080fd5b813567ffffffffffffffff8111156104a757600080fd5b820160a081850312156104b957600080fd5b9392505050565b602080825282518282018190526000919060409081850190868401855b82811015610502578151805185528601518685015292840192908501906001016104dd565b5091979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261054457600080fd5b83018035915067ffffffffffffffff82111561055f57600080fd5b6020019150600581901b360382131561057757600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105ee57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761063b5761063b6105f5565b92915050565b600082610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082018082111561063b5761063b6105f556fea26469706673582212203173ed46160404f3b14f4fd0083f41a6dc2af18a770895f9f6b979ec34adfdaf64736f6c63430008110033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.