Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"@openzeppelin/contracts/math/Math.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
"
},
"@openzeppelin/contracts/math/SignedSafeMath.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @title SignedSafeMath
* @dev Signed math operations with safety checks that revert on error.
*/
library SignedSafeMath {
int256 constant private _INT256_MIN = -2**255;
/**
* @dev Returns the multiplication of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two signed integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
return c;
}
/**
* @dev Returns the subtraction of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
/**
* @dev Returns the addition of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}
}
"
},
"contracts/interfaces/IAggregatorV3Interface.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
interface IAggregatorV3Interface {
function decimals() external view returns (uint8);
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
"
},
"contracts/interfaces/IAssetHandler.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
pragma abicoder v2;
interface IAssetHandler {
event AddedAsset(address asset, uint16 assetType, address aggregator);
event RemovedAsset(address asset);
struct Asset {
address asset;
uint16 assetType;
address aggregator;
}
function addAsset(address asset, uint16 assetType, address aggregator) external;
function addAssets(Asset[] memory assets) external;
function removeAsset(address asset) external;
function priceAggregators(address asset) external view returns (address);
function assetTypes(address asset) external view returns (uint16);
function getUSDPrice(address asset) external view returns (uint256);
}
"
},
"contracts/interfaces/IPoolFactory.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
interface IPoolFactory {
function governanceAddress() external view returns (address);
function isPool(address pool) external view returns (bool);
function customCooldownWhitelist(address from) external view returns (bool);
function receiverWhitelist(address to) external view returns (bool);
function emitPoolEvent() external;
function emitPoolManagerEvent() external;
function isValidAsset(address asset) external view returns (bool);
function getAssetPrice(address asset) external view returns (uint256);
function getAssetHandler() external view returns (address);
}
"
},
"contracts/priceAggregators/PendlePTPriceAggregator.sol": {
"content": "//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2025 dHEDGE DAO
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {Math} from "@openzeppelin/contracts/math/Math.sol";
import {SignedSafeMath} from "@openzeppelin/contracts/math/SignedSafeMath.sol";
import {IPoolFactory} from "../interfaces/IPoolFactory.sol";
import {IAggregatorV3Interface} from "../interfaces/IAggregatorV3Interface.sol";
import {UnderlyingAssetOracleUpdater} from "./UnderlyingAssetOracleUpdater.sol";
contract PendlePTPriceAggregator is IAggregatorV3Interface, UnderlyingAssetOracleUpdater {
using Math for uint256;
using SignedSafeMath for int256;
IAggregatorV3Interface public immutable pendleChainlinkOracle;
uint8 public immutable pendleChainlinkOracleDecimals;
constructor(
address _syEquivalentToken,
IAggregatorV3Interface _pendleChainlinkOracle,
IPoolFactory _poolFactory
) UnderlyingAssetOracleUpdater(_syEquivalentToken, _poolFactory) {
require(address(_pendleChainlinkOracle) != address(0), "invalid address");
pendleChainlinkOracle = _pendleChainlinkOracle;
pendleChainlinkOracleDecimals = _pendleChainlinkOracle.decimals();
}
function decimals() external pure override returns (uint8) {
return 8;
}
function latestRoundData()
external
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
(, int256 ptPrice, , uint256 ptPriceUpdateAt, ) = pendleChainlinkOracle.latestRoundData();
(, int256 underlyingPrice, , uint256 underlyingUpdatedAt, ) = underlyingAggregator.latestRoundData();
// Answer is in underlyingAggregator decimals
answer = (ptPrice.mul(underlyingPrice)).div(int256(10 ** pendleChainlinkOracleDecimals));
// Adjust answer to 8 decimals
answer = answer.mul(1e8).div(int256(10 ** underlyingAggregatorDecimals));
return (0, answer, 0, underlyingUpdatedAt.min(ptPriceUpdateAt), 0);
}
}
"
},
"contracts/priceAggregators/UnderlyingAssetOracleUpdater.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;
import {IAggregatorV3Interface} from "../interfaces/IAggregatorV3Interface.sol";
import {IAssetHandler} from "../interfaces/IAssetHandler.sol";
import {IPoolFactory} from "../interfaces/IPoolFactory.sol";
abstract contract UnderlyingAssetOracleUpdater {
address public underlyingAsset;
IPoolFactory public poolFactory;
IAggregatorV3Interface public underlyingAggregator;
uint8 public underlyingAggregatorDecimals;
constructor(address _underlyingAsset, IPoolFactory _poolFactory) {
require(address(_poolFactory) != address(0) && _underlyingAsset != address(0), "invalid address");
underlyingAsset = _underlyingAsset;
poolFactory = _poolFactory;
updateUnderlyingAggregator();
}
/// @dev In case the underlying asset aggregator is changed within our system, anyone can call this function to update the child aggregator (eliminates the need for redeploying the contract)
function updateUnderlyingAggregator() public {
address _underlyingAggregator = IAssetHandler(poolFactory.getAssetHandler()).priceAggregators(underlyingAsset);
require(_underlyingAggregator != address(0), "invalid aggregator");
uint8 _underlyingAggregatorDecimals = IAggregatorV3Interface(_underlyingAggregator).decimals();
require(_underlyingAggregatorDecimals > 0, "invalid decimals");
underlyingAggregator = IAggregatorV3Interface(_underlyingAggregator);
underlyingAggregatorDecimals = _underlyingAggregatorDecimals;
}
}
"
}
},
"settings": {
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"optimizer": {
"enabled": true,
"runs": 20
}
}
}}
Submitted on: 2025-11-07 10:45:48
Comments
Log in to comment.
No comments yet.