Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
interface IAggregatorV3 {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(
uint80 _roundId
)
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
interface ICegaState {
function marketMakerAllowList(address marketMaker) external view returns (bool);
function products(string memory productName) external view returns (address);
function oracleAddresses(string memory oracleName) external view returns (address);
function oracleNames() external view returns (string[] memory);
function productNames() external view returns (string[] memory);
function feeRecipient() external view returns (address);
function isDefaultAdmin(address sender) external view returns (bool);
function isTraderAdmin(address sender) external view returns (bool);
function isOperatorAdmin(address sender) external view returns (bool);
function isServiceAdmin(address sender) external view returns (bool);
function getOracleNames() external view returns (string[] memory);
function addOracle(string memory oracleName, address oracleAddress) external;
function removeOracle(string memory oracleName) external;
function getProductNames() external view returns (string[] memory);
function addProduct(string memory productName, address product) external;
function removeProduct(string memory productName) external;
function updateMarketMakerPermission(address marketMaker, bool allow) external;
function setFeeRecipient(address _feeRecipient) external;
function moveAssetsToProduct(string memory productName, address vaultAddress, uint256 amount) external;
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import { IAggregatorV3 } from "./interfaces/IAggregatorV3.sol";
import { ICegaState } from "./interfaces/ICegaState.sol";
import { RoundData } from "./Structs.sol";
contract Oracle is IAggregatorV3 {
event OracleCreated(address indexed cegaState, uint8 decimals, string description);
event RoundDataAdded(int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
event RoundDataUpdated(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
uint8 public decimals;
string public description;
uint256 public version = 1;
ICegaState public cegaState;
RoundData[] public oracleData;
uint80 public nextRoundId;
/**
* @notice Creates a new oracle for a given asset / data source pair
* @param _cegaState is the address of the CegaState contract
* @param _decimals is the number of decimals for the asset
* @param _description is the aset
*/
constructor(address _cegaState, uint8 _decimals, string memory _description) {
cegaState = ICegaState(_cegaState);
decimals = _decimals;
description = _description;
emit OracleCreated(_cegaState, _decimals, _description);
}
/**
* @notice Asserts whether the sender has the SERVICE_ADMIN_ROLE
*/
modifier onlyServiceAdmin() {
require(cegaState.isServiceAdmin(msg.sender), "403:SA");
_;
}
/**
* @notice Asserts whether the sender has the DEFAULT_ADMIN_ROLE
*/
modifier onlyDefaultAdmin() {
require(cegaState.isDefaultAdmin(msg.sender), "403:DA");
_;
}
/**
* @notice Adds the pricing data for the next round
* @param _roundData is the data to be added
*/
function addNextRoundData(RoundData calldata _roundData) public onlyServiceAdmin {
if (nextRoundId != 0) {
(, , , uint256 updatedAt, ) = latestRoundData();
require(updatedAt <= _roundData.startedAt, "400:P");
}
require(block.timestamp - 1 days <= _roundData.startedAt, "400:T"); // Within 1 days
oracleData.push(_roundData);
nextRoundId++;
emit RoundDataAdded(_roundData.answer, _roundData.startedAt, _roundData.updatedAt, _roundData.answeredInRound);
}
/**
* @notice Updates the pricing data for a given round
* @param _roundData is the data to be updated
*/
function updateRoundData(uint80 roundId, RoundData calldata _roundData) public onlyDefaultAdmin {
oracleData[roundId] = _roundData;
emit RoundDataUpdated(
roundId,
_roundData.answer,
_roundData.startedAt,
_roundData.updatedAt,
_roundData.answeredInRound
);
}
/**
* @notice Gets the pricing data for a given round Id
* @param _roundId is the id of the round
*/
function getRoundData(
uint80 _roundId
)
public
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
return (
_roundId,
oracleData[_roundId].answer,
oracleData[_roundId].startedAt,
oracleData[_roundId].updatedAt,
oracleData[_roundId].answeredInRound
);
}
/**
* @notice Gets the pricing data for the latest round
*/
function latestRoundData()
public
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
uint80 _roundId = nextRoundId - 1;
return (
_roundId,
oracleData[_roundId].answer,
oracleData[_roundId].startedAt,
oracleData[_roundId].updatedAt,
oracleData[_roundId].answeredInRound
);
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
enum OptionBarrierType {
None,
KnockIn
}
struct Deposit {
uint256 amount;
address receiver;
}
struct Withdrawal {
uint256 amountShares;
address receiver;
}
enum VaultStatus {
DepositsClosed,
DepositsOpen,
NotTraded,
Traded,
TradeExpired,
PayoffCalculated,
FeesCollected,
WithdrawalQueueProcessed,
Zombie
}
struct OptionBarrier {
uint256 barrierBps;
uint256 barrierAbsoluteValue;
uint256 strikeBps;
uint256 strikeAbsoluteValue;
string asset;
string oracleName;
OptionBarrierType barrierType;
}
struct FCNVaultMetadata {
uint256 vaultStart;
uint256 tradeDate;
uint256 tradeExpiry;
uint256 aprBps;
uint256 tenorInDays;
uint256 underlyingAmount; // This is how many assets were ever deposited into the vault
uint256 currentAssetAmount; // This is how many assets are currently allocated for the vault (not sent for trade)
uint256 totalCouponPayoff;
uint256 vaultFinalPayoff;
uint256 queuedWithdrawalsSharesAmount;
uint256 queuedWithdrawalsCount;
uint256 optionBarriersCount;
uint256 leverage;
address vaultAddress;
VaultStatus vaultStatus;
bool isKnockedIn;
OptionBarrier[] optionBarriers;
}
struct RoundData {
int256 answer;
uint256 startedAt;
uint256 updatedAt;
uint80 answeredInRound;
}