Overview
FRAX Balance | FXTL Balance
FRAX Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| GENESIS_fcc0d36e1df115e3b334ed06e5b45c375107fc60 | 0x60806040 | 0 | 724 days ago | GENESIS | IN | 0 FRAX | 0 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x7C880115...21F389f51 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ================= FraxtalERC4626TransportOracle ====================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// ====================================================================
import { Timelock2Step } from "frax-std/access-control/v1/Timelock2Step.sol";
import { ITimelock2Step } from "frax-std/access-control/v1/interfaces/ITimelock2Step.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol";
import { SafeCastLib } from "@solmate/utils/SafeCastLib.sol";
/// @dev High/low prices will be equivalent and return the L1 CL Oracle result
contract FraxtalERC4626TransportOracle is Timelock2Step, ERC165Storage {
using FixedPointMathLib for uint256;
using SafeCastLib for uint256;
address public priceSource;
uint256 public storedTotalAssets;
uint256 public totalSupply;
/// @notice The timestamp of the last time rewards were distributed
uint256 public lastRewardsDistribution;
uint256 public maxDistributionPerSecondPerAsset;
uint96 public lastL1Block;
/// @notice Information about the current rewards cycle
struct RewardsCycleData {
uint40 cycleEnd; // Timestamp of the end of the current rewards cycle
uint40 lastSync; // Timestamp of the last time the rewards cycle was synced
uint216 rewardCycleAmount; // Amount of rewards to be distributed in the current cycle
}
/// @notice The rewards cycle data, stored in a single word to save gas
RewardsCycleData public rewardsCycleData;
constructor(address _timelock, address _priceSource) {
_setTimelock({ _newTimelock: _timelock });
_registerInterface({ interfaceId: type(ITimelock2Step).interfaceId });
priceSource = _priceSource;
}
// ====================================================================
// Internal Configuration Setters
// ====================================================================
/// @notice The ```_setPriceSource``` function sets the price source
/// @param _newPriceSource The new price source
function _setPriceSource(address _newPriceSource) internal {
address _priceSource = priceSource;
if (_priceSource == _newPriceSource) revert SamePriceSource();
emit SetPriceSource({ oldPriceSource: _priceSource, newPriceSource: _newPriceSource });
priceSource = _newPriceSource;
}
// ====================================================================
// Configuration Setters
// ====================================================================
/// @notice The ```setPriceSource``` function sets the price source
/// @dev Requires msg.sender to be the timelock address
/// @param _newPriceSource The new price source address
function setPriceSource(address _newPriceSource) external {
_requireTimelock();
_setPriceSource({ _newPriceSource: _newPriceSource });
}
// ====================================================================
// View Helpers
// ====================================================================
/// @notice The ```description``` function returns the description of the contract
/// @return _description The description of the contract
function description() external pure returns (string memory _description) {
_description = "sFRAX/FRAX: Rate Transport";
}
function name() external pure returns (string memory _name) {
_name = "sFRAX/FRAX: Rate Transport";
}
/// @notice The ```decimals``` function returns same decimals value as CL Oracle
/// @return _decimals The decimals corresponding to the CL answer being transported to L2
/// @dev Needed for ingesting CL feed into Frax Oracles
function decimals() external pure returns (uint8 _decimals) {
_decimals = 18;
}
/// @notice Conforms to the ERC4626 Interface
function pricePerShare() public view returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? 1e18 : uint256(1e18).mulDivDown(totalAssets(), supply);
}
/// @notice The ```previewDistributeRewards``` function is used to preview the rewards distributed at the top of the block
/// @return _rewardToDistribute The amount of underlying to distribute
function previewDistributeRewards() public view virtual returns (uint256 _rewardToDistribute) {
// Cache state for gas savings
RewardsCycleData memory _rewardsCycleData = rewardsCycleData;
uint256 _lastRewardsDistribution = lastRewardsDistribution;
uint40 _timestamp = uint40(block.timestamp);
// Calculate the delta time, but only include up to the cycle end in case we are passed it
uint256 _deltaTime = _timestamp > _rewardsCycleData.cycleEnd
? _rewardsCycleData.cycleEnd - _lastRewardsDistribution
: _timestamp - _lastRewardsDistribution;
// Calculate the rewards to distribute
_rewardToDistribute = calculateRewardsToDistribute({
_rewardsCycleData: _rewardsCycleData,
_deltaTime: _deltaTime
});
}
/// @notice The ```calculateRewardsToDistribute``` function calculates the amount of rewards to distribute based on the rewards cycle data and the time elapsed
/// @param _rewardsCycleData The rewards cycle data
/// @param _deltaTime The time elapsed since the last rewards distribution
/// @return _rewardToDistribute The amount of rewards to distribute
function calculateRewardsToDistribute(
RewardsCycleData memory _rewardsCycleData,
uint256 _deltaTime
) public view virtual returns (uint256 _rewardToDistribute) {
_rewardToDistribute =
(_rewardsCycleData.rewardCycleAmount * _deltaTime) /
(_rewardsCycleData.cycleEnd - _rewardsCycleData.lastSync);
uint256 _maxDistribution = (maxDistributionPerSecondPerAsset * _deltaTime * storedTotalAssets) / 1e18;
if (_rewardToDistribute > _maxDistribution) {
_rewardToDistribute = _maxDistribution;
}
}
/// @notice The ```totalAssets``` function returns the total assets available in the vault
/// @dev This function simulates the rewards that will be distributed at the top of the block
/// @return _totalAssets The total assets available in the vault
function totalAssets() public view virtual returns (uint256 _totalAssets) {
uint256 _rewardToDistribute = previewDistributeRewards();
_totalAssets = storedTotalAssets + _rewardToDistribute;
}
function _getPrices() internal view returns (bool isBadData, uint256 _priceLow, uint256 _priceHigh) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
uint256 fraxPerSfrax = supply == 0 ? 1e18 : uint256(1e18).mulDivDown(totalAssets(), supply);
_priceLow = _priceHigh = fraxPerSfrax;
isBadData = false;
}
/// @notice The ```getPrices``` function is intended to return two prices from different oracles
/// @return isBadData is true when data is stale or otherwise bad
/// @return _priceLow is the lower of the two prices
/// @return _priceHigh is the higher of the two prices
function getPrices() external view returns (bool isBadData, uint256 _priceLow, uint256 _priceHigh) {
(isBadData, _priceLow, _priceHigh) = _getPrices();
}
/// @dev Adheres to chainlink's AggregatorV3Interface
/// @return roundId The l1Block corresponding to the last time the oracle was proofed
/// @return answer The price of Sfrax in frax
/// @return startedAt The current timestamp
/// @return updatedAt The current timestamp
/// @return answeredInRound The l1Block corresponding to the last time the oracle was proofed
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
answeredInRound = roundId = uint80(lastL1Block);
startedAt = updatedAt = block.timestamp;
answer = int256(pricePerShare());
if (answer < 0) revert CastError();
if (roundId < 0) revert CastError();
}
// ====================================================================
// Relay functions from merkle prover
// ====================================================================
/// TODO: natspec
function updatesFRAXData(
uint96 _l1BlockNumber,
uint256 _totalSupply,
uint256 _totalAssets,
uint256 _lastRewardsDistribution,
RewardsCycleData memory _data
) external {
if (msg.sender != priceSource) revert OnlyPriceSource();
if (_l1BlockNumber < lastL1Block) revert StalePush();
rewardsCycleData = _data;
lastRewardsDistribution = _lastRewardsDistribution;
totalSupply = _totalSupply;
storedTotalAssets = _totalAssets;
emit VaultDataUpdated(totalSupply, storedTotalAssets, lastRewardsDistribution, rewardsCycleData);
}
/// TODO: natspec
function updateMaxDistributionPerSecond(uint96 _l1BlockNumber, uint256 _maxPerSecond) external {
if (msg.sender != priceSource) revert OnlyPriceSource();
if (_l1BlockNumber < lastL1Block) revert StalePush();
maxDistributionPerSecondPerAsset = _maxPerSecond;
emit MaxDistributionPerSecondPerAssetUpdated(maxDistributionPerSecondPerAsset);
}
// ====================================================================
// Events
// ====================================================================
/// @notice The ```SetPriceSource``` event is emitted when the price source is set
/// @param oldPriceSource The old price source address
/// @param newPriceSource The new price source address
event SetPriceSource(address oldPriceSource, address newPriceSource);
event VaultDataUpdated(
uint256 totalSupply,
uint256 totalStoredAssets,
uint256 lastRewardsDistribution,
RewardsCycleData data
);
event MaxDistributionPerSecondPerAssetUpdated(uint256 newMax);
// ====================================================================
// Errors
// ====================================================================
error OnlyPriceSource();
error SamePriceSource();
error StalePush();
error CastError();
}// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================== Timelock2Step ===========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Primary Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
/// @title Timelock2Step
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @dev Inspired by the OpenZeppelin's Ownable2Step contract
/// @notice An abstract contract which contains 2-step transfer and renounce logic for a timelock address
abstract contract Timelock2Step {
/// @notice The pending timelock address
address public pendingTimelockAddress;
/// @notice The current timelock address
address public timelockAddress;
constructor() {
timelockAddress = msg.sender;
}
/// @notice Emitted when timelock is transferred
error OnlyTimelock();
/// @notice Emitted when pending timelock is transferred
error OnlyPendingTimelock();
/// @notice The ```TimelockTransferStarted``` event is emitted when the timelock transfer is initiated
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```TimelockTransferred``` event is emitted when the timelock transfer is completed
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```_isSenderTimelock``` function checks if msg.sender is current timelock address
/// @return Whether or not msg.sender is current timelock address
function _isSenderTimelock() internal view returns (bool) {
return msg.sender == timelockAddress;
}
/// @notice The ```_requireTimelock``` function reverts if msg.sender is not current timelock address
function _requireTimelock() internal view {
if (msg.sender != timelockAddress) revert OnlyTimelock();
}
/// @notice The ```_isSenderPendingTimelock``` function checks if msg.sender is pending timelock address
/// @return Whether or not msg.sender is pending timelock address
function _isSenderPendingTimelock() internal view returns (bool) {
return msg.sender == pendingTimelockAddress;
}
/// @notice The ```_requirePendingTimelock``` function reverts if msg.sender is not pending timelock address
function _requirePendingTimelock() internal view {
if (msg.sender != pendingTimelockAddress) revert OnlyPendingTimelock();
}
/// @notice The ```_transferTimelock``` function initiates the timelock transfer
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the nominated (pending) timelock
function _transferTimelock(address _newTimelock) internal {
pendingTimelockAddress = _newTimelock;
emit TimelockTransferStarted(timelockAddress, _newTimelock);
}
/// @notice The ```_acceptTransferTimelock``` function completes the timelock transfer
/// @dev This function is to be implemented by a public function
function _acceptTransferTimelock() internal {
pendingTimelockAddress = address(0);
_setTimelock(msg.sender);
}
/// @notice The ```_setTimelock``` function sets the timelock address
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the new timelock
function _setTimelock(address _newTimelock) internal {
emit TimelockTransferred(timelockAddress, _newTimelock);
timelockAddress = _newTimelock;
}
/// @notice The ```transferTimelock``` function initiates the timelock transfer
/// @dev Must be called by the current timelock
/// @param _newTimelock The address of the nominated (pending) timelock
function transferTimelock(address _newTimelock) external virtual {
_requireTimelock();
_transferTimelock(_newTimelock);
}
/// @notice The ```acceptTransferTimelock``` function completes the timelock transfer
/// @dev Must be called by the pending timelock
function acceptTransferTimelock() external virtual {
_requirePendingTimelock();
_acceptTransferTimelock();
}
/// @notice The ```renounceTimelock``` function renounces the timelock after setting pending timelock to current timelock
/// @dev Pending timelock must be set to current timelock before renouncing, creating a 2-step renounce process
function renounceTimelock() external virtual {
_requireTimelock();
_requirePendingTimelock();
_transferTimelock(address(0));
_setTimelock(address(0));
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;
interface ITimelock2Step {
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
function acceptTransferTimelock() external;
function pendingTimelockAddress() external view returns (address);
function renounceTimelock() external;
function timelockAddress() external view returns (address);
function transferTimelock(address _newTimelock) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165Storage is ERC165 {
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*//////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}
/*//////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// Divide z by the denominator.
z := div(z, denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// First, divide z - 1 by the denominator and add 1.
// We allow z - 1 to underflow if z is 0, because we multiply the
// end result by 0 if z is zero, ensuring we return 0 if z is zero.
z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
}
}
function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, scalar)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}
/*//////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// Start off with z at 1.
z := 1
// Used below to help find a nearby power of 2.
let y := x
// Find the lowest power of 2 that is at least sqrt(x).
if iszero(lt(y, 0x100000000000000000000000000000000)) {
y := shr(128, y) // Like dividing by 2 ** 128.
z := shl(64, z) // Like multiplying by 2 ** 64.
}
if iszero(lt(y, 0x10000000000000000)) {
y := shr(64, y) // Like dividing by 2 ** 64.
z := shl(32, z) // Like multiplying by 2 ** 32.
}
if iszero(lt(y, 0x100000000)) {
y := shr(32, y) // Like dividing by 2 ** 32.
z := shl(16, z) // Like multiplying by 2 ** 16.
}
if iszero(lt(y, 0x10000)) {
y := shr(16, y) // Like dividing by 2 ** 16.
z := shl(8, z) // Like multiplying by 2 ** 8.
}
if iszero(lt(y, 0x100)) {
y := shr(8, y) // Like dividing by 2 ** 8.
z := shl(4, z) // Like multiplying by 2 ** 4.
}
if iszero(lt(y, 0x10)) {
y := shr(4, y) // Like dividing by 2 ** 4.
z := shl(2, z) // Like multiplying by 2 ** 2.
}
if iszero(lt(y, 0x8)) {
// Equivalent to 2 ** z.
z := shl(1, z)
}
// Shifting right by 1 is like dividing by 2.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// Compute a rounded down version of z.
let zRoundDown := div(x, z)
// If zRoundDown is smaller, use it.
if lt(zRoundDown, z) {
z := zRoundDown
}
}
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Safe unsigned integer casting library that reverts on overflow.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
function safeCastTo248(uint256 x) internal pure returns (uint248 y) {
require(x < 1 << 248);
y = uint248(x);
}
function safeCastTo224(uint256 x) internal pure returns (uint224 y) {
require(x < 1 << 224);
y = uint224(x);
}
function safeCastTo192(uint256 x) internal pure returns (uint192 y) {
require(x < 1 << 192);
y = uint192(x);
}
function safeCastTo160(uint256 x) internal pure returns (uint160 y) {
require(x < 1 << 160);
y = uint160(x);
}
function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
require(x < 1 << 128);
y = uint128(x);
}
function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
require(x < 1 << 96);
y = uint96(x);
}
function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
require(x < 1 << 64);
y = uint64(x);
}
function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
require(x < 1 << 32);
y = uint32(x);
}
function safeCastTo8(uint256 x) internal pure returns (uint8 y) {
require(x < 1 << 8);
y = uint8(x);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"ds-test/=node_modules/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"frax-std/=node_modules/frax-standard-solidity/src/",
"script/=src/script/",
"src/=src/",
"test/=src/test/",
"interfaces/=src/contracts/interfaces/",
"arbitrum/=node_modules/@arbitrum/",
"rlp/=node_modules/solidity-rlp/contracts/",
"@solmate/=node_modules/@rari-capital/solmate/src/",
"@arbitrum/=node_modules/@arbitrum/",
"@chainlink/=node_modules/@chainlink/",
"@eth-optimism/=node_modules/@eth-optimism/",
"@mean-finance/=node_modules/@mean-finance/",
"@offchainlabs/=node_modules/@offchainlabs/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@rari-capital/=node_modules/@rari-capital/",
"@uniswap/=node_modules/@uniswap/",
"base64-sol/=node_modules/base64-sol/",
"frax-standard-solidity/=node_modules/frax-standard-solidity/",
"hardhat/=node_modules/hardhat/",
"prb-math/=node_modules/prb-math/",
"solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
"solidity-rlp/=node_modules/solidity-rlp/"
],
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_timelock","type":"address"},{"internalType":"address","name":"_priceSource","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CastError","type":"error"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyPriceSource","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"inputs":[],"name":"SamePriceSource","type":"error"},{"inputs":[],"name":"StalePush","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"MaxDistributionPerSecondPerAssetUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPriceSource","type":"address"},{"indexed":false,"internalType":"address","name":"newPriceSource","type":"address"}],"name":"SetPriceSource","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStoredAssets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastRewardsDistribution","type":"uint256"},{"components":[{"internalType":"uint40","name":"cycleEnd","type":"uint40"},{"internalType":"uint40","name":"lastSync","type":"uint40"},{"internalType":"uint216","name":"rewardCycleAmount","type":"uint216"}],"indexed":false,"internalType":"struct FraxtalERC4626TransportOracle.RewardsCycleData","name":"data","type":"tuple"}],"name":"VaultDataUpdated","type":"event"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint40","name":"cycleEnd","type":"uint40"},{"internalType":"uint40","name":"lastSync","type":"uint40"},{"internalType":"uint216","name":"rewardCycleAmount","type":"uint216"}],"internalType":"struct FraxtalERC4626TransportOracle.RewardsCycleData","name":"_rewardsCycleData","type":"tuple"},{"internalType":"uint256","name":"_deltaTime","type":"uint256"}],"name":"calculateRewardsToDistribute","outputs":[{"internalType":"uint256","name":"_rewardToDistribute","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"_decimals","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"_description","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPrices","outputs":[{"internalType":"bool","name":"isBadData","type":"bool"},{"internalType":"uint256","name":"_priceLow","type":"uint256"},{"internalType":"uint256","name":"_priceHigh","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastL1Block","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRewardsDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDistributionPerSecondPerAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previewDistributeRewards","outputs":[{"internalType":"uint256","name":"_rewardToDistribute","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceSource","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsCycleData","outputs":[{"internalType":"uint40","name":"cycleEnd","type":"uint40"},{"internalType":"uint40","name":"lastSync","type":"uint40"},{"internalType":"uint216","name":"rewardCycleAmount","type":"uint216"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newPriceSource","type":"address"}],"name":"setPriceSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"storedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"_totalAssets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"transferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_l1BlockNumber","type":"uint96"},{"internalType":"uint256","name":"_maxPerSecond","type":"uint256"}],"name":"updateMaxDistributionPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_l1BlockNumber","type":"uint96"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"uint256","name":"_totalAssets","type":"uint256"},{"internalType":"uint256","name":"_lastRewardsDistribution","type":"uint256"},{"components":[{"internalType":"uint40","name":"cycleEnd","type":"uint40"},{"internalType":"uint40","name":"lastSync","type":"uint40"},{"internalType":"uint216","name":"rewardCycleAmount","type":"uint216"}],"internalType":"struct FraxtalERC4626TransportOracle.RewardsCycleData","name":"_data","type":"tuple"}],"name":"updatesFRAXData","outputs":[],"stateMutability":"nonpayable","type":"function"}]Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061019a575f3560e01c80634bc66f32116100e857806399530b0611610093578063bda531071161006e578063bda5310714610400578063c473071e14610413578063f6ccaad414610426578063feaf968c1461042e575f80fd5b806399530b06146103ca578063bd6f3603146103d2578063bd9a548b146103db575f80fd5b806361c1c5e9116100c357806361c1c5e91461038c5780637284e416146101dc578063770b1c8f14610395575f80fd5b80634bc66f32146102e35780634f8b4ae7146103035780635ebae5661461030b575f80fd5b80632af98d6d11610148578063358245fc11610123578063358245fc146102b5578063374010a4146102bd57806345014095146102d0575f80fd5b80632af98d6d14610288578063313ce56714610291578063330a7355146102a0575f80fd5b8063090f3f5011610178578063090f3f501461021b57806318160ddd1461025f57806320531bc914610268575f80fd5b806301e1d1141461019e57806301ffc9a7146101b957806306fdde03146101dc575b5f80fd5b6101a661046d565b6040519081526020015b60405180910390f35b6101cc6101c7366004610d07565b61048d565b60405190151581526020016101b0565b604080518082018252601a81527f73465241582f465241583a2052617465205472616e73706f7274000000000000602082015290516101b09190610d4d565b5f5461023a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b0565b6101a660055481565b60035461023a9073ffffffffffffffffffffffffffffffffffffffff1681565b6101a660075481565b604051601281526020016101b0565b6102b36102ae366004610dd6565b610514565b005b6101a66105ef565b6101a66102cb366004610ec6565b610692565b6102b36102de366004610eef565b610728565b60015461023a9073ffffffffffffffffffffffffffffffffffffffff1681565b6102b361073c565b600954600a5461034b9164ffffffffff808216926501000000000090920416907affffffffffffffffffffffffffffffffffffffffffffffffffffff1683565b6040805164ffffffffff94851681529390921660208401527affffffffffffffffffffffffffffffffffffffffffffffffffffff16908201526060016101b0565b6101a660045481565b6008546103ad906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff90911681526020016101b0565b6101a6610760565b6101a660065481565b6103e361079a565b6040805193151584526020840192909252908201526060016101b0565b6102b361040e366004610eef565b6107b1565b6102b3610421366004610f22565b6107c2565b6102b3610971565b610436610981565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a0016101b0565b5f806104776105ef565b9050806004546104879190610f9c565b91505090565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061050e57507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526002602052604090205460ff165b92915050565b60035473ffffffffffffffffffffffffffffffffffffffff163314610565576040517f2937b3e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008546bffffffffffffffffffffffff90811690831610156105b3576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60078190556040518181527f46247912ba9c6159cb43222e1f4c98ad2617ee7f476da5a706449e2dab4ea2089060200160405180910390a15050565b6040805160608101825260095464ffffffffff8082168084526501000000000090920481166020840152600a547affffffffffffffffffffffffffffffffffffffffffffffffffffff16938301939093526006545f9390914291859190831611610669576106648364ffffffffff8416610faf565b61067d565b835161067d90849064ffffffffff16610faf565b90506106898482610692565b94505050505090565b602082015182515f916106a491610fc2565b64ffffffffff168284604001517affffffffffffffffffffffffffffffffffffffffffffffffffffff166106d89190610fe0565b6106e29190610ff7565b90505f670de0b6b3a7640000600454846007546106ff9190610fe0565b6107099190610fe0565b6107139190610ff7565b905080821115610721578091505b5092915050565b6107306109e1565b61073981610a32565b50565b6107446109e1565b61074c610aa6565b6107555f610a32565b61075e5f610af6565b565b6005545f90801561078b5761078661077661046d565b670de0b6b3a76400009083610b83565b610487565b670de0b6b3a764000091505090565b5f805f6107a5610ba1565b91959094509092509050565b6107b96109e1565b61073981610be9565b60035473ffffffffffffffffffffffffffffffffffffffff163314610813576040517f2937b3e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008546bffffffffffffffffffffffff9081169086161015610861576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516009805460208085015164ffffffffff90811665010000000000027fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000909316948116949094179190911791829055604080850151600a80547affffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffffff000000000000000000000000000000000000000000000000000000909216821790556006879055600589905560048890558151898152928301889052908201869052828416606083015260289290921c909216608083015260a08201527f070c603364fd4b335a6a4318bfae5f7305c56b9b3d54cb6093122aa3b9f59a369060c00160405180910390a15050505050565b610979610aa6565b61075e610cd7565b6008546bffffffffffffffffffffffff165f42808361099e610760565b93505f8412156109da576040517f811752de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9091929394565b60015473ffffffffffffffffffffffffffffffffffffffff16331461075e576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a9190a350565b5f5473ffffffffffffffffffffffffffffffffffffffff16331461075e576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b828202811515841585830485141716610b9a575f80fd5b0492915050565b6005545f9081908190818115610bd157610bcc610bbc61046d565b670de0b6b3a76400009084610b83565b610bdb565b670de0b6b3a76400005b5f9690955085945092505050565b60035473ffffffffffffffffffffffffffffffffffffffff9081169082168103610c3f576040517f22ba75b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8084168252841660208201527f964298b435edfc268e11aa89b342ef1ddac566da6759b6dd15d7aad58a1dc935910160405180910390a150600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561075e33610af6565b5f60208284031215610d17575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d46575f80fd5b9392505050565b5f6020808352835180828501525f5b81811015610d7857858101830151858201604001528201610d5c565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b80356bffffffffffffffffffffffff81168114610dd1575f80fd5b919050565b5f8060408385031215610de7575f80fd5b610df083610db6565b946020939093013593505050565b803564ffffffffff81168114610dd1575f80fd5b5f60608284031215610e22575f80fd5b6040516060810181811067ffffffffffffffff82111715610e6a577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604052905080610e7983610dfe565b8152610e8760208401610dfe565b602082015260408301357affffffffffffffffffffffffffffffffffffffffffffffffffffff81168114610eb9575f80fd5b6040919091015292915050565b5f8060808385031215610ed7575f80fd5b610ee18484610e12565b946060939093013593505050565b5f60208284031215610eff575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d46575f80fd5b5f805f805f60e08688031215610f36575f80fd5b610f3f86610db6565b9450602086013593506040860135925060608601359150610f638760808801610e12565b90509295509295909350565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082018082111561050e5761050e610f6f565b8181038181111561050e5761050e610f6f565b64ffffffffff82811682821603908082111561072157610721610f6f565b808202811582820484141761050e5761050e610f6f565b5f8261102a577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b50049056fea164736f6c6343000814000a
Net Worth in USD
Net Worth in FRAX
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.