Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SpectraFixedYieldOracle
Compiler Version
v0.8.25+commit.b61c2a91
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { CorrelatedSpectraPTOracle } from "./common/CorrelatedSpectraPTOracle.sol"; import { ensureNonzeroAddress } from "../lib/validators.sol"; /** * @title SpectraFixedYieldOracle * @author Enclabs * @notice This oracle fetches the price of Spectra PT depending on a fixed initial discount and days left to maturity */ contract SpectraFixedYieldOracle is CorrelatedSpectraPTOracle { uint256 private constant SECONDS_PER_YEAR = 365 days; uint256 private constant ONE = 1e18; address public immutable PT; uint256 public immutable maturity; uint256 public immutable baseDiscountPerYear; // 100% = 1e18 /// @notice Constructor for the implementation contract. /// @custom:oz-upgrades-unsafe-allow constructor constructor( address _pt, address _underlying, address _resilientOracle, uint256 _baseDiscountPerYear ) CorrelatedSpectraPTOracle(_pt, _underlying, _resilientOracle) { ensureNonzeroAddress(_pt); ensureNonzeroAddress(_underlying); require(_baseDiscountPerYear <= 1e18, "invalid discount"); require(_pt != address(0), "zero address"); PT = _pt; maturity = PTMaturity(PT).maturity(); baseDiscountPerYear = _baseDiscountPerYear; } function decimals() external pure returns (uint8) { return 18; } function getDiscount( uint256 timeLeft ) public view returns (uint256) { return (timeLeft * baseDiscountPerYear) / SECONDS_PER_YEAR; } /** * @notice Gets the number of underlying for 1 PT at current date * @return amount Amount of underlying */ function _getUnderlyingAmount() internal view override returns (uint256) { uint256 timeLeft = (maturity > block.timestamp) ? maturity - block.timestamp : 0; uint256 discount = getDiscount(timeLeft); require(discount <= ONE, "discount overflow"); return uint256(ONE - discount); } } interface PTMaturity { function maturity() external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.25; interface OracleInterface { function getPrice(address asset) external view returns (uint256); } interface ResilientOracleInterface is OracleInterface { function updatePrice(address vToken) external; function updateAssetPrice(address asset) external; function getUnderlyingPrice(address vToken) external view returns (uint256); } interface TwapInterface is OracleInterface { function updateTwap(address asset) external returns (uint256); } interface BoundValidatorInterface { function validatePriceWithAnchorPrice( address asset, uint256 reporterPrice, uint256 anchorPrice ) external view returns (bool); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { OracleInterface } from "../../Interfaces/OracleInterface.sol"; import { ensureNonzeroAddress } from "../../lib/validators.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /** * @title CorrelatedSpectraPTOracle * @notice This oracle fetches the price of a token that is correlated to another token. */ abstract contract CorrelatedSpectraPTOracle is OracleInterface { /// @notice Address of the correlated token /// @custom:oz-upgrades-unsafe-allow state-variable-immutable address public immutable CORRELATED_TOKEN; /// @notice Address of the underlying token /// @custom:oz-upgrades-unsafe-allow state-variable-immutable address public immutable UNDERLYING_TOKEN; /// @notice Address of Resilient Oracle /// @custom:oz-upgrades-unsafe-allow state-variable-immutable OracleInterface public immutable RESILIENT_ORACLE; /// @notice Thrown if the token address is invalid error InvalidTokenAddress(); /// @notice Constructor for the implementation contract. /// @custom:oz-upgrades-unsafe-allow constructor constructor(address correlatedToken, address underlyingToken, address resilientOracle) { ensureNonzeroAddress(correlatedToken); ensureNonzeroAddress(underlyingToken); ensureNonzeroAddress(resilientOracle); CORRELATED_TOKEN = correlatedToken; UNDERLYING_TOKEN = underlyingToken; RESILIENT_ORACLE = OracleInterface(resilientOracle); } /** * @notice Fetches the price of the correlated token * @param asset Address of the correlated token * @return price The price of the correlated token in scaled decimal places */ function getPrice(address asset) external view override returns (uint256) { if (asset != CORRELATED_TOKEN) revert InvalidTokenAddress(); // get underlying token amount for 1 correlated token scaled by underlying token decimals uint256 underlyingAmount = _getUnderlyingAmount(); // oracle returns (36 - asset decimal) scaled price uint256 underlyingUSDPrice = RESILIENT_ORACLE.getPrice(UNDERLYING_TOKEN); IERC20Metadata token = IERC20Metadata(CORRELATED_TOKEN); uint256 decimals = token.decimals(); // underlyingAmount (for 1 correlated token) * underlyingUSDPrice / decimals(correlated token) return (underlyingAmount * underlyingUSDPrice) / (10 ** decimals * 1e18); } /** * @notice Gets the underlying amount for correlated token * @return underlyingAmount Amount of underlying token */ function _getUnderlyingAmount() internal view virtual returns (uint256); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; /// @notice Thrown if the supplied address is a zero address where it is not allowed error ZeroAddressNotAllowed(); /// @notice Checks if the provided address is nonzero, reverts otherwise /// @param address_ Address to check /// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address function ensureNonzeroAddress(address address_) pure { if (address_ == address(0)) { revert ZeroAddressNotAllowed(); } }
{ "evmVersion": "paris", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_pt","type":"address"},{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"address","name":"_resilientOracle","type":"address"},{"internalType":"uint256","name":"_baseDiscountPerYear","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"inputs":[],"name":"CORRELATED_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESILIENT_ORACLE","outputs":[{"internalType":"contract OracleInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseDiscountPerYear","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeLeft","type":"uint256"}],"name":"getDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
61014060405234801561001157600080fd5b50604051610990380380610990833981016040819052610030916101d2565b83838361003c8361018c565b6100458261018c565b61004e8161018c565b6001600160a01b0392831660805290821660a0521660c05261006f8461018c565b6100788361018c565b670de0b6b3a76400008111156100c85760405162461bcd60e51b815260206004820152601060248201526f1a5b9d985b1a5908191a5cd8dbdd5b9d60821b60448201526064015b60405180910390fd5b6001600160a01b03841661010d5760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b60448201526064016100bf565b6001600160a01b03841660e08190526040805163204f83f960e01b8152905163204f83f9916004808201926020929091908290030181865afa158015610157573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017b919061021d565b610100526101205250610236915050565b6001600160a01b0381166101b3576040516342bcdf7f60e11b815260040160405180910390fd5b50565b80516001600160a01b03811681146101cd57600080fd5b919050565b600080600080608085870312156101e857600080fd5b6101f1856101b6565b93506101ff602086016101b6565b925061020d604086016101b6565b6060959095015193969295505050565b60006020828403121561022f57600080fd5b5051919050565b60805160a05160c05160e05161010051610120516106dc6102b46000396000818161014b01526101ee015260008181609d015281816104020152610433015260006101c001526000818161019901526102c601526000818160ea015261029801526000818161017201528181610227015261033701526106dc6000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c806341976e091161006657806341976e0914610133578063598e54511461014657806369818a351461016d578063a4edcd4c14610194578063d94073d4146101bb57600080fd5b8063204f83f9146100985780632336dbe4146100d257806329db1be6146100e5578063313ce56714610124575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf6100e03660046104cf565b6101e2565b61010c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c9565b604051601281526020016100c9565b6100bf6101413660046104e8565b610223565b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b61010c7f000000000000000000000000000000000000000000000000000000000000000081565b61010c7f000000000000000000000000000000000000000000000000000000000000000081565b61010c7f000000000000000000000000000000000000000000000000000000000000000081565b60006301e133806102137f00000000000000000000000000000000000000000000000000000000000000008461052e565b61021d9190610545565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461027757604051630f58058360e11b815260040160405180910390fd5b60006102816103fc565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa15801561030d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103319190610567565b905060007f000000000000000000000000000000000000000000000000000000000000000090506000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103bc9190610580565b60ff1690506103cc81600a610687565b6103de90670de0b6b3a764000061052e565b6103e8848661052e565b6103f29190610545565b9695505050505050565b600080427f00000000000000000000000000000000000000000000000000000000000000001161042d576000610457565b610457427f0000000000000000000000000000000000000000000000000000000000000000610693565b90506000610464826101e2565b9050670de0b6b3a76400008111156104b65760405162461bcd60e51b8152602060048201526011602482015270646973636f756e74206f766572666c6f7760781b604482015260640160405180910390fd5b6104c881670de0b6b3a7640000610693565b9250505090565b6000602082840312156104e157600080fd5b5035919050565b6000602082840312156104fa57600080fd5b81356001600160a01b038116811461051157600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761021d5761021d610518565b60008261056257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561057957600080fd5b5051919050565b60006020828403121561059257600080fd5b815160ff8116811461051157600080fd5b600181815b808511156105de5781600019048211156105c4576105c4610518565b808516156105d157918102915b93841c93908002906105a8565b509250929050565b6000826105f55750600161021d565b816106025750600061021d565b816001811461061857600281146106225761063e565b600191505061021d565b60ff84111561063357610633610518565b50506001821b61021d565b5060208310610133831016604e8410600b8410161715610661575081810a61021d565b61066b83836105a3565b806000190482111561067f5761067f610518565b029392505050565b600061051183836105e6565b8181038181111561021d5761021d61051856fea2646970667358221220fec97807b830f6f400f606f7cdd8d6b9dd1a44e7a9f55985196c60fee2c3e2e964736f6c634300081900330000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d000000000000000000000000d3dce716f3ef535c5ff8d041c1a41c3bd89b97ae000000000000000000000000d05b05590609c3610161e60eb41ec317c75624080000000000000000000000000000000000000000000000000b1a2bc2ec500000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c806341976e091161006657806341976e0914610133578063598e54511461014657806369818a351461016d578063a4edcd4c14610194578063d94073d4146101bb57600080fd5b8063204f83f9146100985780632336dbe4146100d257806329db1be6146100e5578063313ce56714610124575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000006861d38781565b6040519081526020015b60405180910390f35b6100bf6100e03660046104cf565b6101e2565b61010c7f000000000000000000000000d3dce716f3ef535c5ff8d041c1a41c3bd89b97ae81565b6040516001600160a01b0390911681526020016100c9565b604051601281526020016100c9565b6100bf6101413660046104e8565b610223565b6100bf7f0000000000000000000000000000000000000000000000000b1a2bc2ec50000081565b61010c7f0000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d81565b61010c7f000000000000000000000000d05b05590609c3610161e60eb41ec317c756240881565b61010c7f0000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d81565b60006301e133806102137f0000000000000000000000000000000000000000000000000b1a2bc2ec5000008461052e565b61021d9190610545565b92915050565b60007f0000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d6001600160a01b0316826001600160a01b03161461027757604051630f58058360e11b815260040160405180910390fd5b60006102816103fc565b6040516341976e0960e01b81526001600160a01b037f000000000000000000000000d3dce716f3ef535c5ff8d041c1a41c3bd89b97ae811660048301529192506000917f000000000000000000000000d05b05590609c3610161e60eb41ec317c756240816906341976e0990602401602060405180830381865afa15801561030d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103319190610567565b905060007f0000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d90506000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103bc9190610580565b60ff1690506103cc81600a610687565b6103de90670de0b6b3a764000061052e565b6103e8848661052e565b6103f29190610545565b9695505050505050565b600080427f000000000000000000000000000000000000000000000000000000006861d3871161042d576000610457565b610457427f000000000000000000000000000000000000000000000000000000006861d387610693565b90506000610464826101e2565b9050670de0b6b3a76400008111156104b65760405162461bcd60e51b8152602060048201526011602482015270646973636f756e74206f766572666c6f7760781b604482015260640160405180910390fd5b6104c881670de0b6b3a7640000610693565b9250505090565b6000602082840312156104e157600080fd5b5035919050565b6000602082840312156104fa57600080fd5b81356001600160a01b038116811461051157600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761021d5761021d610518565b60008261056257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561057957600080fd5b5051919050565b60006020828403121561059257600080fd5b815160ff8116811461051157600080fd5b600181815b808511156105de5781600019048211156105c4576105c4610518565b808516156105d157918102915b93841c93908002906105a8565b509250929050565b6000826105f55750600161021d565b816106025750600061021d565b816001811461061857600281146106225761063e565b600191505061021d565b60ff84111561063357610633610518565b50506001821b61021d565b5060208310610133831016604e8410600b8410161715610661575081810a61021d565b61066b83836105a3565b806000190482111561067f5761067f610518565b029392505050565b600061051183836105e6565b8181038181111561021d5761021d61051856fea2646970667358221220fec97807b830f6f400f606f7cdd8d6b9dd1a44e7a9f55985196c60fee2c3e2e964736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d000000000000000000000000d3dce716f3ef535c5ff8d041c1a41c3bd89b97ae000000000000000000000000d05b05590609c3610161e60eb41ec317c75624080000000000000000000000000000000000000000000000000b1a2bc2ec500000
-----Decoded View---------------
Arg [0] : _pt (address): 0x7002383d2305B8f3b2b7786F50C13D132A22076d
Arg [1] : _underlying (address): 0xd3DCe716f3eF535C5Ff8d041c1A41C3bd89b97aE
Arg [2] : _resilientOracle (address): 0xd05b05590609c3610161e60eb41eC317c7562408
Arg [3] : _baseDiscountPerYear (uint256): 800000000000000000
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000007002383d2305b8f3b2b7786f50c13d132a22076d
Arg [1] : 000000000000000000000000d3dce716f3ef535c5ff8d041c1a41c3bd89b97ae
Arg [2] : 000000000000000000000000d05b05590609c3610161e60eb41ec317c7562408
Arg [3] : 0000000000000000000000000000000000000000000000000b1a2bc2ec500000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.