Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
ERC4626Oracle
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 { IERC4626 } from "../interfaces/IERC4626.sol";
import { CorrelatedTokenOracle } from "./common/CorrelatedTokenOracle.sol";
/**
* @title ERC4626Oracle
* @author Venus
* @notice This oracle fetches the price of ERC4626 tokens
*/
contract ERC4626Oracle is CorrelatedTokenOracle {
uint256 public immutable ONE_CORRELATED_TOKEN;
/// @notice Constructor for the implementation contract.
constructor(
address correlatedToken,
address underlyingToken,
address resilientOracle,
uint256 annualGrowthRate,
uint256 _snapshotInterval,
uint256 initialSnapshotMaxExchangeRate,
uint256 initialSnapshotTimestamp,
address accessControlManager,
uint256 _snapshotGap
)
CorrelatedTokenOracle(
correlatedToken,
underlyingToken,
resilientOracle,
annualGrowthRate,
_snapshotInterval,
initialSnapshotMaxExchangeRate,
initialSnapshotTimestamp,
accessControlManager,
_snapshotGap
)
{
ONE_CORRELATED_TOKEN = 10 ** IERC4626(correlatedToken).decimals();
}
/**
* @notice Fetches the amount of underlying token for 1 correlated token
* @return amount The amount of underlying token for correlated token
*/
function getUnderlyingAmount() public view override returns (uint256) {
return IERC4626(CORRELATED_TOKEN).convertToAssets(ONE_CORRELATED_TOKEN);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}// 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;
import "@openzeppelin/contracts/access/IAccessControl.sol";
/**
* @title IAccessControlManagerV8
* @author Venus
* @notice Interface implemented by the `AccessControlManagerV8` contract.
*/
interface IAccessControlManagerV8 is IAccessControl {
function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;
function revokeCallPermission(
address contractAddress,
string calldata functionSig,
address accountToRevoke
) external;
function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);
function hasPermission(
address account,
address contractAddress,
string calldata functionSig
) external view returns (bool);
}// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.25; /// @dev Base unit for computations, usually used in scaling (multiplications, divisions) uint256 constant EXP_SCALE = 1e18; /// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions uint256 constant MANTISSA_ONE = EXP_SCALE; /// @dev The approximate number of seconds per year uint256 constant SECONDS_PER_YEAR = 31_536_000;
// 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 Thrown if the supplied value is 0 where it is not allowed
error ZeroValueNotAllowed();
/// @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();
}
}
/// @notice Checks if the provided value is nonzero, reverts otherwise
/// @param value_ Value to check
/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0
function ensureNonzeroValue(uint256 value_) pure {
if (value_ == 0) {
revert ZeroValueNotAllowed();
}
}// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.25;
interface ICappedOracle {
function updateSnapshot() external;
}// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.25;
interface IERC4626 {
function convertToAssets(uint256 shares) external view returns (uint256);
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 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, ResilientOracleInterface } from "../../interfaces/OracleInterface.sol";
import { ensureNonzeroAddress } from "@venusprotocol/solidity-utilities/contracts/validators.sol";
import { SECONDS_PER_YEAR } from "@venusprotocol/solidity-utilities/contracts/constants.sol";
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { ICappedOracle } from "../../interfaces/ICappedOracle.sol";
import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol";
/**
* @title CorrelatedTokenOracle
* @notice This oracle fetches the price of a token that is correlated to another token.
*/
abstract contract CorrelatedTokenOracle is OracleInterface, ICappedOracle {
/// @notice Address of the correlated token
address public immutable CORRELATED_TOKEN;
/// @notice Address of the underlying token
address public immutable UNDERLYING_TOKEN;
/// @notice Address of Resilient Oracle
ResilientOracleInterface public immutable RESILIENT_ORACLE;
/// @notice Address of the AccessControlManager contract
IAccessControlManagerV8 public immutable ACCESS_CONTROL_MANAGER;
//// @notice Growth rate percentage in seconds. Ex: 1e18 is 100%
uint256 public growthRatePerSecond;
/// @notice Snapshot update interval
uint256 public snapshotInterval;
/// @notice Last stored snapshot maximum exchange rate
uint256 public snapshotMaxExchangeRate;
/// @notice Last stored snapshot timestamp
uint256 public snapshotTimestamp;
/// @notice Gap to add when updating the snapshot
uint256 public snapshotGap;
/// @notice Emitted when the snapshot is updated
event SnapshotUpdated(uint256 indexed maxExchangeRate, uint256 indexed timestamp);
/// @notice Emitted when the growth rate is updated
event GrowthRateUpdated(
uint256 indexed oldGrowthRatePerSecond,
uint256 indexed newGrowthRatePerSecond,
uint256 indexed oldSnapshotInterval,
uint256 newSnapshotInterval
);
/// @notice Emitted when the snapshot gap is updated
event SnapshotGapUpdated(uint256 indexed oldSnapshotGap, uint256 indexed newSnapshotGap);
/// @notice Thrown if the token address is invalid
error InvalidTokenAddress();
/// @notice Thrown if the growth rate is invalid
error InvalidGrowthRate();
/// @notice Thrown if the initial snapshot is invalid
error InvalidInitialSnapshot();
/// @notice Thrown if the max snapshot exchange rate is invalid
error InvalidSnapshotMaxExchangeRate();
/// @notice @notice Thrown when the action is prohibited by AccessControlManager
error Unauthorized(address sender, address calledContract, string methodSignature);
/**
* @notice Constructor for the implementation contract.
* @custom:error InvalidGrowthRate error is thrown if the growth rate is invalid
* @custom:error InvalidInitialSnapshot error is thrown if the initial snapshot values are invalid
*/
constructor(
address _correlatedToken,
address _underlyingToken,
address _resilientOracle,
uint256 _annualGrowthRate,
uint256 _snapshotInterval,
uint256 _initialSnapshotMaxExchangeRate,
uint256 _initialSnapshotTimestamp,
address _accessControlManager,
uint256 _snapshotGap
) {
growthRatePerSecond = _annualGrowthRate / SECONDS_PER_YEAR;
if ((growthRatePerSecond == 0 && _snapshotInterval > 0) || (growthRatePerSecond > 0 && _snapshotInterval == 0))
revert InvalidGrowthRate();
if ((_initialSnapshotMaxExchangeRate == 0 || _initialSnapshotTimestamp == 0) && _snapshotInterval > 0) {
revert InvalidInitialSnapshot();
}
ensureNonzeroAddress(_correlatedToken);
ensureNonzeroAddress(_underlyingToken);
ensureNonzeroAddress(_resilientOracle);
ensureNonzeroAddress(_accessControlManager);
CORRELATED_TOKEN = _correlatedToken;
UNDERLYING_TOKEN = _underlyingToken;
RESILIENT_ORACLE = ResilientOracleInterface(_resilientOracle);
snapshotInterval = _snapshotInterval;
snapshotMaxExchangeRate = _initialSnapshotMaxExchangeRate;
snapshotTimestamp = _initialSnapshotTimestamp;
snapshotGap = _snapshotGap;
ACCESS_CONTROL_MANAGER = IAccessControlManagerV8(_accessControlManager);
}
/**
* @notice Directly sets the snapshot exchange rate and timestamp
* @param _snapshotMaxExchangeRate The exchange rate to set
* @param _snapshotTimestamp The timestamp to set
* @custom:event Emits SnapshotUpdated event on successful update of the snapshot
*/
function setSnapshot(uint256 _snapshotMaxExchangeRate, uint256 _snapshotTimestamp) external {
_checkAccessAllowed("setSnapshot(uint256,uint256)");
snapshotMaxExchangeRate = _snapshotMaxExchangeRate;
snapshotTimestamp = _snapshotTimestamp;
emit SnapshotUpdated(snapshotMaxExchangeRate, snapshotTimestamp);
}
/**
* @notice Sets the growth rate and snapshot interval
* @param _annualGrowthRate The annual growth rate to set
* @param _snapshotInterval The snapshot interval to set
* @custom:error InvalidGrowthRate error is thrown if the growth rate is invalid
* @custom:event Emits GrowthRateUpdated event on successful update of the growth rate
*/
function setGrowthRate(uint256 _annualGrowthRate, uint256 _snapshotInterval) external {
_checkAccessAllowed("setGrowthRate(uint256,uint256)");
uint256 oldGrowthRatePerSecond = growthRatePerSecond;
growthRatePerSecond = _annualGrowthRate / SECONDS_PER_YEAR;
if ((growthRatePerSecond == 0 && _snapshotInterval > 0) || (growthRatePerSecond > 0 && _snapshotInterval == 0))
revert InvalidGrowthRate();
emit GrowthRateUpdated(oldGrowthRatePerSecond, growthRatePerSecond, snapshotInterval, _snapshotInterval);
snapshotInterval = _snapshotInterval;
}
/**
* @notice Sets the snapshot gap
* @param _snapshotGap The snapshot gap to set
* @custom:event Emits SnapshotGapUpdated event on successful update of the snapshot gap
*/
function setSnapshotGap(uint256 _snapshotGap) external {
_checkAccessAllowed("setSnapshotGap(uint256)");
emit SnapshotGapUpdated(snapshotGap, _snapshotGap);
snapshotGap = _snapshotGap;
}
/**
* @notice Returns if the price is capped
* @return isCapped Boolean indicating if the price is capped
*/
function isCapped() external view virtual returns (bool) {
if (snapshotInterval == 0) {
return false;
}
uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();
if (maxAllowedExchangeRate == 0) {
return false;
}
uint256 exchangeRate = getUnderlyingAmount();
return exchangeRate > maxAllowedExchangeRate;
}
/**
* @notice Updates the snapshot price and timestamp
* @custom:event Emits SnapshotUpdated event on successful update of the snapshot
* @custom:error InvalidSnapshotMaxExchangeRate error is thrown if the max snapshot exchange rate is zero
*/
function updateSnapshot() public override {
if (block.timestamp - snapshotTimestamp < snapshotInterval || snapshotInterval == 0) return;
uint256 exchangeRate = getUnderlyingAmount();
uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();
snapshotMaxExchangeRate =
(exchangeRate > maxAllowedExchangeRate ? maxAllowedExchangeRate : exchangeRate) +
snapshotGap;
snapshotTimestamp = block.timestamp;
if (snapshotMaxExchangeRate == 0) revert InvalidSnapshotMaxExchangeRate();
RESILIENT_ORACLE.updateAssetPrice(UNDERLYING_TOKEN);
emit SnapshotUpdated(snapshotMaxExchangeRate, snapshotTimestamp);
}
/**
* @notice Fetches the price of the token
* @param asset Address of the token
* @return price The price of the token in scaled decimal places. It can be capped
* to a maximum value taking into account the growth rate
* @custom:error InvalidTokenAddress error is thrown if the token address is invalid
*/
function getPrice(address asset) public view override returns (uint256) {
if (asset != CORRELATED_TOKEN) revert InvalidTokenAddress();
uint256 exchangeRate = getUnderlyingAmount();
if (snapshotInterval == 0) {
return _calculatePrice(exchangeRate);
}
uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();
uint256 finalExchangeRate = (exchangeRate > maxAllowedExchangeRate && maxAllowedExchangeRate != 0)
? maxAllowedExchangeRate
: exchangeRate;
return _calculatePrice(finalExchangeRate);
}
/**
* @notice Gets the maximum allowed exchange rate for token
* @return maxExchangeRate Maximum allowed exchange rate
*/
function getMaxAllowedExchangeRate() public view returns (uint256) {
uint256 timeElapsed = block.timestamp - snapshotTimestamp;
uint256 maxExchangeRate = snapshotMaxExchangeRate +
(snapshotMaxExchangeRate * growthRatePerSecond * timeElapsed) /
1e18;
return maxExchangeRate;
}
/**
* @notice Gets the underlying amount for correlated token
* @return underlyingAmount Amount of underlying token
*/
function getUnderlyingAmount() public view virtual returns (uint256);
/**
* @notice Fetches price of the token based on an underlying exchange rate
* @param exchangeRate The underlying exchange rate to use
* @return price The price of the token in scaled decimal places
*/
function _calculatePrice(uint256 exchangeRate) internal view returns (uint256) {
uint256 underlyingUSDPrice = RESILIENT_ORACLE.getPrice(UNDERLYING_TOKEN);
IERC20Metadata token = IERC20Metadata(CORRELATED_TOKEN);
uint256 decimals = token.decimals();
return (exchangeRate * underlyingUSDPrice) / (10 ** decimals);
}
/**
* @notice Reverts if the call is not allowed by AccessControlManager
* @param signature Method signature
* @custom:error Unauthorized error is thrown if the call is not allowed
*/
function _checkAccessAllowed(string memory signature) internal view {
bool isAllowedToCall = ACCESS_CONTROL_MANAGER.isAllowedToCall(msg.sender, signature);
if (!isAllowedToCall) {
revert Unauthorized(msg.sender, address(this), signature);
}
}
}{
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"correlatedToken","type":"address"},{"internalType":"address","name":"underlyingToken","type":"address"},{"internalType":"address","name":"resilientOracle","type":"address"},{"internalType":"uint256","name":"annualGrowthRate","type":"uint256"},{"internalType":"uint256","name":"_snapshotInterval","type":"uint256"},{"internalType":"uint256","name":"initialSnapshotMaxExchangeRate","type":"uint256"},{"internalType":"uint256","name":"initialSnapshotTimestamp","type":"uint256"},{"internalType":"address","name":"accessControlManager","type":"address"},{"internalType":"uint256","name":"_snapshotGap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidGrowthRate","type":"error"},{"inputs":[],"name":"InvalidInitialSnapshot","type":"error"},{"inputs":[],"name":"InvalidSnapshotMaxExchangeRate","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"calledContract","type":"address"},{"internalType":"string","name":"methodSignature","type":"string"}],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldGrowthRatePerSecond","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newGrowthRatePerSecond","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"oldSnapshotInterval","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newSnapshotInterval","type":"uint256"}],"name":"GrowthRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldSnapshotGap","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newSnapshotGap","type":"uint256"}],"name":"SnapshotGapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"maxExchangeRate","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SnapshotUpdated","type":"event"},{"inputs":[],"name":"ACCESS_CONTROL_MANAGER","outputs":[{"internalType":"contract IAccessControlManagerV8","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CORRELATED_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_CORRELATED_TOKEN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESILIENT_ORACLE","outputs":[{"internalType":"contract ResilientOracleInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxAllowedExchangeRate","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":"getUnderlyingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"growthRatePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isCapped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_annualGrowthRate","type":"uint256"},{"internalType":"uint256","name":"_snapshotInterval","type":"uint256"}],"name":"setGrowthRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_snapshotMaxExchangeRate","type":"uint256"},{"internalType":"uint256","name":"_snapshotTimestamp","type":"uint256"}],"name":"setSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_snapshotGap","type":"uint256"}],"name":"setSnapshotGap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshotGap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snapshotInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snapshotMaxExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snapshotTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
610120604052348015610010575f80fd5b5060405161109938038061109983398101604081905261002f916101d2565b8888888888888888886100466301e1338087610265565b5f81905515801561005657505f85115b8061006a57505f805411801561006a575084155b15610088576040516353b7e64560e11b815260040160405180910390fd5b831580610093575082155b801561009e57505f85115b156100bc5760405163b8a5589b60e01b815260040160405180910390fd5b6100c58961018d565b6100ce8861018d565b6100d78761018d565b6100e08261018d565b6001600160a01b0398891660805296881660a05294871660c052600192909255600255600355506004918255821660e0526040805163313ce56760e01b81529051928c169263313ce567928281019260209291908290030181865afa15801561014b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061016f9190610284565b61017a90600a61038d565b610100525061039b975050505050505050565b6001600160a01b0381166101b4576040516342bcdf7f60e11b815260040160405180910390fd5b50565b80516001600160a01b03811681146101cd575f80fd5b919050565b5f805f805f805f805f6101208a8c0312156101eb575f80fd5b6101f48a6101b7565b985061020260208b016101b7565b975061021060408b016101b7565b965060608a0151955060808a0151945060a08a0151935060c08a0151925061023a60e08b016101b7565b91506101008a015190509295985092959850929598565b634e487b7160e01b5f52601160045260245ffd5b5f8261027f57634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215610294575f80fd5b815160ff811681146102a4575f80fd5b9392505050565b600181815b808511156102e557815f19048211156102cb576102cb610251565b808516156102d857918102915b93841c93908002906102b0565b509250929050565b5f826102fb57506001610387565b8161030757505f610387565b816001811461031d576002811461032757610343565b6001915050610387565b60ff84111561033857610338610251565b50506001821b610387565b5060208310610133831016604e8410600b8410161715610366575081810a610387565b61037083836102ab565b805f190482111561038357610383610251565b0290505b92915050565b5f6102a460ff8416836102ed565b60805160a05160c05160e05161010051610c826104175f395f818161024301526106b001525f8181610191015261090b01525f81816102730152818161059c01526107de01525f81816101360152818161057401526107b201525f8181610209015281816102b0015281816106d8015261084c0152610c825ff3fe608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063692404261161009e5780639c43eb541161006e5780639c43eb5414610265578063a4edcd4c1461026e578063abb8561314610295578063ac5a693e1461029d578063bdf13af2146102a5575f80fd5b806369240426146101fc57806369818a35146102045780637fc4e4a01461022b57806386f23a751461023e575f80fd5b806345be2dc7116100e457806345be2dc71461018c5780635213f9c8146101b3578063596efe6f146101c8578063643d813d146101d1578063671528d4146101e4575f80fd5b806307d0413c1461011557806329db1be6146101315780634169d2451461017057806341976e0914610179575b5f80fd5b61011e60015481565b6040519081526020015b60405180910390f35b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610128565b61011e60045481565b61011e6101873660046109b4565b6102ad565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101c66101c13660046109da565b61035e565b005b61011e60025481565b6101c66101df3660046109f1565b6103cf565b6101ec6104a5565b6040519015158152602001610128565b6101c66104e0565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101c66102393660046109f1565b610629565b61011e7f000000000000000000000000000000000000000000000000000000000000000081565b61011e60035481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b61011e6106a1565b61011e5f5481565b61011e61074e565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461030057604051630f58058360e11b815260040160405180910390fd5b5f6103096106a1565b90506001545f036103245761031d8161079b565b9392505050565b5f61032d61074e565b90505f818311801561033e57508115155b610348578261034a565b815b90506103558161079b565b95945050505050565b61039c6040518060400160405280601781526020017f736574536e617073686f744761702875696e74323536290000000000000000008152506108f2565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61040d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e743235362900008152506108f2565b5f5461041d6301e1338084610a25565b5f81905515801561042d57505f82115b8061044157505f8054118015610441575081155b1561045f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161049691815260200190565b60405180910390a45060015550565b5f6001545f036104b457505f90565b5f6104bd61074e565b9050805f036104cd575f91505090565b5f6104d66106a1565b9190911192915050565b6001546003546104f09042610a44565b10806104fc5750600154155b1561050357565b5f61050c6106a1565b90505f61051761074e565b9050600454818311610529578261052b565b815b6105359190610a5d565b6002819055426003555f0361055d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156105dd575f80fd5b505af11580156105ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6106676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e7432353629000000008152506108f2565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b6040516303d1689d60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307a2d13a90602401602060405180830381865afa158015610725573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107499190610a70565b905090565b5f806003544261075e9190610a44565b90505f670de0b6b3a7640000825f5460025461077a9190610a87565b6107849190610a87565b61078e9190610a25565b60025461031d9190610a5d565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610823573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108479190610a70565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108ce9190610a9e565b60ff1690506108de81600a610b9e565b6108e88487610a87565b6103559190610a25565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab906109429033908690600401610bd7565b602060405180830381865afa15801561095d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109819190610c02565b9050806109b057333083604051634a3fa29360e01b81526004016109a793929190610c21565b60405180910390fd5b5050565b5f602082840312156109c4575f80fd5b81356001600160a01b038116811461031d575f80fd5b5f602082840312156109ea575f80fd5b5035919050565b5f8060408385031215610a02575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610a3f57634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610a5757610a57610a11565b92915050565b80820180821115610a5757610a57610a11565b5f60208284031215610a80575f80fd5b5051919050565b8082028115828204841417610a5757610a57610a11565b5f60208284031215610aae575f80fd5b815160ff8116811461031d575f80fd5b600181815b80851115610af857815f1904821115610ade57610ade610a11565b80851615610aeb57918102915b93841c9390800290610ac3565b509250929050565b5f82610b0e57506001610a57565b81610b1a57505f610a57565b8160018114610b305760028114610b3a57610b56565b6001915050610a57565b60ff841115610b4b57610b4b610a11565b50506001821b610a57565b5060208310610133831016604e8410600b8410161715610b79575081810a610a57565b610b838383610abe565b805f1904821115610b9657610b96610a11565b029392505050565b5f61031d8383610b00565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610bfa90830184610ba9565b949350505050565b5f60208284031215610c12575f80fd5b8151801515811461031d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061035590830184610ba956fea2646970667358221220769bd4507ee4baa59dc1ffbb2b118f4231d4085409ae12a75a4688ff934c134f64736f6c6343000819003300000000000000000000000002b1136d9e223333e0083aeab76bc441f230a0330000000000000000000000004200000000000000000000000000000000000006000000000000000000000000c34871c982cf0bc6e7aca2c2670bc319bda1c7440000000000000000000000000000000000000000000000000214e8348c4f0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000681877c6000000000000000000000000724138223d8f76b519fde715f60124e7ce51e0510000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063692404261161009e5780639c43eb541161006e5780639c43eb5414610265578063a4edcd4c1461026e578063abb8561314610295578063ac5a693e1461029d578063bdf13af2146102a5575f80fd5b806369240426146101fc57806369818a35146102045780637fc4e4a01461022b57806386f23a751461023e575f80fd5b806345be2dc7116100e457806345be2dc71461018c5780635213f9c8146101b3578063596efe6f146101c8578063643d813d146101d1578063671528d4146101e4575f80fd5b806307d0413c1461011557806329db1be6146101315780634169d2451461017057806341976e0914610179575b5f80fd5b61011e60015481565b6040519081526020015b60405180910390f35b6101587f000000000000000000000000420000000000000000000000000000000000000681565b6040516001600160a01b039091168152602001610128565b61011e60045481565b61011e6101873660046109b4565b6102ad565b6101587f000000000000000000000000724138223d8f76b519fde715f60124e7ce51e05181565b6101c66101c13660046109da565b61035e565b005b61011e60025481565b6101c66101df3660046109f1565b6103cf565b6101ec6104a5565b6040519015158152602001610128565b6101c66104e0565b6101587f00000000000000000000000002b1136d9e223333e0083aeab76bc441f230a03381565b6101c66102393660046109f1565b610629565b61011e7f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b61011e60035481565b6101587f000000000000000000000000c34871c982cf0bc6e7aca2c2670bc319bda1c74481565b61011e6106a1565b61011e5f5481565b61011e61074e565b5f7f00000000000000000000000002b1136d9e223333e0083aeab76bc441f230a0336001600160a01b0316826001600160a01b03161461030057604051630f58058360e11b815260040160405180910390fd5b5f6103096106a1565b90506001545f036103245761031d8161079b565b9392505050565b5f61032d61074e565b90505f818311801561033e57508115155b610348578261034a565b815b90506103558161079b565b95945050505050565b61039c6040518060400160405280601781526020017f736574536e617073686f744761702875696e74323536290000000000000000008152506108f2565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61040d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e743235362900008152506108f2565b5f5461041d6301e1338084610a25565b5f81905515801561042d57505f82115b8061044157505f8054118015610441575081155b1561045f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161049691815260200190565b60405180910390a45060015550565b5f6001545f036104b457505f90565b5f6104bd61074e565b9050805f036104cd575f91505090565b5f6104d66106a1565b9190911192915050565b6001546003546104f09042610a44565b10806104fc5750600154155b1561050357565b5f61050c6106a1565b90505f61051761074e565b9050600454818311610529578261052b565b815b6105359190610a5d565b6002819055426003555f0361055d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000004200000000000000000000000000000000000006811660048301527f000000000000000000000000c34871c982cf0bc6e7aca2c2670bc319bda1c744169063b62cad69906024015f604051808303815f87803b1580156105dd575f80fd5b505af11580156105ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6106676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e7432353629000000008152506108f2565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b6040516303d1689d60e11b81527f0000000000000000000000000000000000000000000000000de0b6b3a764000060048201525f907f00000000000000000000000002b1136d9e223333e0083aeab76bc441f230a0336001600160a01b0316906307a2d13a90602401602060405180830381865afa158015610725573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107499190610a70565b905090565b5f806003544261075e9190610a44565b90505f670de0b6b3a7640000825f5460025461077a9190610a87565b6107849190610a87565b61078e9190610a25565b60025461031d9190610a5d565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000004200000000000000000000000000000000000006811660048301525f9182917f000000000000000000000000c34871c982cf0bc6e7aca2c2670bc319bda1c74416906341976e0990602401602060405180830381865afa158015610823573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108479190610a70565b90505f7f00000000000000000000000002b1136d9e223333e0083aeab76bc441f230a03390505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108ce9190610a9e565b60ff1690506108de81600a610b9e565b6108e88487610a87565b6103559190610a25565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000724138223d8f76b519fde715f60124e7ce51e05116906318c5e8ab906109429033908690600401610bd7565b602060405180830381865afa15801561095d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109819190610c02565b9050806109b057333083604051634a3fa29360e01b81526004016109a793929190610c21565b60405180910390fd5b5050565b5f602082840312156109c4575f80fd5b81356001600160a01b038116811461031d575f80fd5b5f602082840312156109ea575f80fd5b5035919050565b5f8060408385031215610a02575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610a3f57634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610a5757610a57610a11565b92915050565b80820180821115610a5757610a57610a11565b5f60208284031215610a80575f80fd5b5051919050565b8082028115828204841417610a5757610a57610a11565b5f60208284031215610aae575f80fd5b815160ff8116811461031d575f80fd5b600181815b80851115610af857815f1904821115610ade57610ade610a11565b80851615610aeb57918102915b93841c9390800290610ac3565b509250929050565b5f82610b0e57506001610a57565b81610b1a57505f610a57565b8160018114610b305760028114610b3a57610b56565b6001915050610a57565b60ff841115610b4b57610b4b610a11565b50506001821b610a57565b5060208310610133831016604e8410600b8410161715610b79575081810a610a57565b610b838383610abe565b805f1904821115610b9657610b96610a11565b029392505050565b5f61031d8383610b00565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610bfa90830184610ba9565b949350505050565b5f60208284031215610c12575f80fd5b8151801515811461031d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061035590830184610ba956fea2646970667358221220769bd4507ee4baa59dc1ffbb2b118f4231d4085409ae12a75a4688ff934c134f64736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000002b1136d9e223333e0083aeab76bc441f230a0330000000000000000000000004200000000000000000000000000000000000006000000000000000000000000c34871c982cf0bc6e7aca2c2670bc319bda1c7440000000000000000000000000000000000000000000000000214e8348c4f0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000681877c6000000000000000000000000724138223d8f76b519fde715f60124e7ce51e0510000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : correlatedToken (address): 0x02B1136d9E223333E0083aeAB76bC441f230a033
Arg [1] : underlyingToken (address): 0x4200000000000000000000000000000000000006
Arg [2] : resilientOracle (address): 0xC34871C982cf0Bc6e7aCa2c2670Bc319bDA1C744
Arg [3] : annualGrowthRate (uint256): 150000000000000000
Arg [4] : _snapshotInterval (uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935
Arg [5] : initialSnapshotMaxExchangeRate (uint256): 1000000000000000000
Arg [6] : initialSnapshotTimestamp (uint256): 1746433990
Arg [7] : accessControlManager (address): 0x724138223D8F76b519fdE715f60124E7Ce51e051
Arg [8] : _snapshotGap (uint256): 0
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000002b1136d9e223333e0083aeab76bc441f230a033
Arg [1] : 0000000000000000000000004200000000000000000000000000000000000006
Arg [2] : 000000000000000000000000c34871c982cf0bc6e7aca2c2670bc319bda1c744
Arg [3] : 0000000000000000000000000000000000000000000000000214e8348c4f0000
Arg [4] : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Arg [5] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [6] : 00000000000000000000000000000000000000000000000000000000681877c6
Arg [7] : 000000000000000000000000724138223d8f76b519fde715f60124e7ce51e051
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.