scrvUSD Crosschain Oracle
ScrvusdOracleV2.vyPrice Methods
The contract has three different functions for the scrvUSD share price (or its inverse when setting _i = 1) using different approximations:
price_v0provides a lower-bound estimate of the scrvUSD share price (or its inverse when _i is 1) by combining a historically smoothed price with a raw price derived from previous vault parameters.price_v1returns an approximate share price (or its inverse when _i is 1) by calculating a raw price based on current timestamp data and stored parameters, assuming no external interactions have altered it.price_v2offers an alternative approximation (or its inverse when _i is 1) that factors in expected rewards accrual by using current block timestamps for both the price and parameter calculations.
update_price
ScrvusdOracleV2.update_price(_parameters: uint256[ALL_PARAM_CNT], _ts: uint256, _block_number: uint256) -> uint256This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the PRICE_PARAMETERS_VERIFIER role.
Function to update the price using scrvUSD vault parameters.
Returns: absolute relative price change of the final price with 10^18 precision (uint256).
Emits: PriceUpdate event.
| Input | Type | Description |
|---|---|---|
_parameters | uint256[ALL_PARAM_CNT] | Parameters of the Yearn Vault |
_ts | uint256 | Timestamp at which the parameters are true |
_block_number | uint256 | Block number of parameters to linearize updates |
<>Source code▼
event PriceUpdate:
new_price: uint256 # price to achieve
price_params_ts: uint256 # timestamp at which price is recorded
block_number: uint256
# scrvUSD Vault rate replication
ALL_PARAM_CNT: constant(uint256) = 2 + 5
MAX_BPS_EXTENDED: constant(uint256) = 1_000_000_000_000
last_block_number: public(uint256) # Warning: used both for price parameters and unlock_time
# smoothening
last_prices: uint256[3]
last_update: uint256
# scrvUSD replication parameters
profit_max_unlock_time: public(uint256)
price_params: PriceParams
price_params_ts: uint256
@external
def update_price(
_parameters: uint256[ALL_PARAM_CNT], _ts: uint256, _block_number: uint256
) -> uint256:
"""
@notice Update price using `_parameters`
@param _parameters Parameters of Yearn Vault to calculate scrvUSD price
@param _ts Timestamp at which these parameters are true
@param _block_number Block number of parameters to linearize updates
@return Absolute relative price change of final price with 10^18 precision
"""
access_control._check_role(PRICE_PARAMETERS_VERIFIER, msg.sender)
# Allowing same block updates for fixing bad blockhash provided (if possible)
assert self.last_block_number <= _block_number, "Outdated"
self.last_block_number = _block_number
self.last_prices = [self._price_v0(), self._price_v1(), self._price_v2()]
self.last_update = block.timestamp
ts: uint256 = self.price_params_ts
current_price: uint256 = self._raw_price(ts, ts)
self.price_params = PriceParams(
total_debt=_parameters[0],
total_idle=_parameters[1],
total_supply=_parameters[2],
full_profit_unlock_date=_parameters[3],
profit_unlocking_rate=_parameters[4],
last_profit_update=_parameters[5],
balance_of_self=_parameters[6],
)
self.price_params_ts = _ts
new_price: uint256 = self._raw_price(_ts, _ts)
log PriceUpdate(new_price, _ts, _block_number)
if new_price > current_price:
return (new_price - current_price) * 10**18 // current_price
return (current_price - new_price) * 10**18 // current_price
@view
def _price_v0() -> uint256:
return self._smoothed_price(
self.last_prices[0],
self._raw_price(self.price_params_ts, self.price_params.last_profit_update),
)
@view
def _price_v1() -> uint256:
return self._smoothed_price(
self.last_prices[1], self._raw_price(block.timestamp, self.price_params_ts)
)
@view
def _price_v2() -> uint256:
return self._smoothed_price(
self.last_prices[2], self._raw_price(block.timestamp, block.timestamp)
)
@view
def _smoothed_price(last_price: uint256, raw_price: uint256) -> uint256:
# Ideally should be (max_price_increment / 10**18) **(block.timestamp - self.last_update)
# Using linear approximation to simplify calculations
max_change: uint256 = (
self.max_price_increment * (block.timestamp - self.last_update) * last_price // 10**18
)
# -max_change <= (raw_price - last_price) <= max_change
if unsafe_sub(raw_price + max_change, last_price) > 2 * max_change:
return last_price + max_change if raw_price > last_price else last_price - max_change
return raw_price
@view
def _raw_price(ts: uint256, parameters_ts: uint256) -> uint256:
"""
@notice Price replication from scrvUSD vault
"""
parameters: PriceParams = self._obtain_price_params(parameters_ts)
return self._total_assets(parameters) * 10**18 // self._total_supply(parameters, ts)
▶Example▼
This example updates the price of scrvUSD.
>>> ScrvusdOracleV2.update_price()
raw_price
ScrvusdOracleV2.raw_price(_i: uint256 = 0, _ts: uint256 = block.timestamp, _parameters_ts: uint256 = block.timestamp) -> uint256: viewFunction to compute the raw approximated share or asset price without smoothening out.
Returns: raw pricePerShare() or pricePerAsset() (uint256).
| Input | Type | Description |
|---|---|---|
_i | uint256 | 0 for pricePerShare() and 1 for pricePerAsset(); defaults to 0 |
_ts | uint256 | Timestamp at which to see the price (only near period is supported) |
_parameters_ts | uint256 | Timestamp for the price parameters |
<>Source code▼
@view
@external
def raw_price(
_i: uint256 = 0, _ts: uint256 = block.timestamp, _parameters_ts: uint256 = block.timestamp
) -> uint256:
"""
@notice Get approximate `scrvUSD.pricePerShare()` without smoothening
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
@param _ts Timestamp at which to see price (only near period is supported)
"""
p: uint256 = self._raw_price(_ts, _parameters_ts)
return p if _i == 0 else 10**36 // p
@view
def _raw_price(ts: uint256, parameters_ts: uint256) -> uint256:
"""
@notice Price replication from scrvUSD vault
"""
parameters: PriceParams = self._obtain_price_params(parameters_ts)
return self._total_assets(parameters) * 10**18 // self._total_supply(parameters, ts)
@view
def _obtain_price_params(parameters_ts: uint256) -> PriceParams:
"""
@notice Obtain Price parameters true or assumed to be true at `parameters_ts`.
Assumes constant gain(in crvUSD rewards) through distribution periods.
@param parameters_ts Timestamp to obtain parameters for
@return Assumed `PriceParams`
"""
params: PriceParams = self.price_params
period: uint256 = self.profit_max_unlock_time
if params.last_profit_update + period >= parameters_ts:
return params
number_of_periods: uint256 = min(
(parameters_ts - params.last_profit_update) // period,
self.max_v2_duration,
)
# locked shares at moment params.last_profit_update
gain: uint256 = (
params.balance_of_self * (params.total_idle + params.total_debt) // params.total_supply
)
params.total_idle += gain * number_of_periods
# functions are reduced from `VaultV3._process_report()` given assumptions with constant gain
for _: uint256 in range(number_of_periods, bound=MAX_V2_DURATION):
new_balance_of_self: uint256 = (
params.balance_of_self
* (params.total_supply - params.balance_of_self) // params.total_supply
)
params.total_supply -= (
params.balance_of_self * params.balance_of_self // params.total_supply
)
params.balance_of_self = new_balance_of_self
if params.full_profit_unlock_date > params.last_profit_update:
# copy from `VaultV3._process_report()`
params.profit_unlocking_rate = params.balance_of_self * MAX_BPS_EXTENDED // (
params.full_profit_unlock_date - params.last_profit_update
)
else:
params.profit_unlocking_rate = 0
params.full_profit_unlock_date += number_of_periods * period
params.last_profit_update += number_of_periods * period
return params
@view
def _total_assets(p: PriceParams) -> uint256:
"""
@notice Total amount of assets that are in the vault and in the strategies.
"""
return p.total_idle + p.total_debt
@view
def _total_supply(p: PriceParams, ts: uint256) -> uint256:
# Need to account for the shares issued to the vault that have unlocked.
return p.total_supply - self._unlocked_shares(
p.full_profit_unlock_date,
p.profit_unlocking_rate,
p.last_profit_update,
p.balance_of_self,
ts, # block.timestamp
)
▶Example▼
This example returns the raw share or asset price of scrvUSD.
ScrvusdOracleV2.raw_price(0)
# returns pricePerShare()
ScrvusdOracleV2.raw_price(1)
# returns pricePerAsset()
price_v0
ScrvusdOracleV2.price_v0(_i: uint256 = 0) -> uint256: viewGetter for the lower bound of the share or asset price.
Returns: lower bound of pricePerShare() (uint256).
| Input | Type | Description |
|---|---|---|
_i | uint256 | 0 for pricePerShare() and 1 for pricePerAsset() |
<>Source code▼
struct PriceParams:
# assets
total_debt: uint256
total_idle: uint256
# supply
total_supply: uint256
full_profit_unlock_date: uint256
profit_unlocking_rate: uint256
last_profit_update: uint256
balance_of_self: uint256
last_block_number: public(uint256) # Warning: used both for price parameters and unlock_time
# smoothening
last_prices: uint256[3]
last_update: uint256
# scrvUSD replication parameters
profit_max_unlock_time: public(uint256)
price_params: PriceParams
price_params_ts: uint256
max_price_increment: public(uint256) # precision 10**18
max_v2_duration: public(uint256) # number of periods(weeks)
@view
@external
def price_v0(_i: uint256 = 0) -> uint256:
"""
@notice Get lower bound of `scrvUSD.pricePerShare()`
@dev Price is updated in steps, need to verify every % changed
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
"""
return self._price_v0() if _i == 0 else 10**36 // self._price_v0()
@view
def _price_v0() -> uint256:
return self._smoothed_price(
self.last_prices[0],
self._raw_price(self.price_params_ts, self.price_params.last_profit_update),
)
@view
def _smoothed_price(last_price: uint256, raw_price: uint256) -> uint256:
# Ideally should be (max_price_increment / 10**18) **(block.timestamp - self.last_update)
# Using linear approximation to simplify calculations
max_change: uint256 = (
self.max_price_increment * (block.timestamp - self.last_update) * last_price // 10**18
)
# -max_change <= (raw_price - last_price) <= max_change
if unsafe_sub(raw_price + max_change, last_price) > 2 * max_change:
return last_price + max_change if raw_price > last_price else last_price - max_change
return raw_price
@view
@external
def raw_price(
_i: uint256 = 0, _ts: uint256 = block.timestamp, _parameters_ts: uint256 = block.timestamp
) -> uint256:
"""
@notice Get approximate `scrvUSD.pricePerShare()` without smoothening
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
@param _ts Timestamp at which to see price (only near period is supported)
"""
p: uint256 = self._raw_price(_ts, _parameters_ts)
return p if _i == 0 else 10**36 // p
▶Example▼
This example returns the lower bound of pricePerShare() or pricePerAsset().
ScrvusdOracleV2.price_v0(0)
# returns pricePerShare()
ScrvusdOracleV2.price_v0(1)
# returns pricePerAsset()
price_v1
ScrvusdOracleV2.price_v1(_i: uint256 = 0) -> uint256: viewGetter for the approximate share or asset price assuming no new interactions.
Returns: approximate pricePerShare() (uint256).
| Input | Type | Description |
|---|---|---|
_i | uint256 | 0 for pricePerShare() and 1 for pricePerAsset() |
<>Source code▼
struct PriceParams:
# assets
total_debt: uint256
total_idle: uint256
# supply
total_supply: uint256
full_profit_unlock_date: uint256
profit_unlocking_rate: uint256
last_profit_update: uint256
balance_of_self: uint256
last_block_number: public(uint256) # Warning: used both for price parameters and unlock_time
# smoothening
last_prices: uint256[3]
last_update: uint256
# scrvUSD replication parameters
profit_max_unlock_time: public(uint256)
price_params: PriceParams
price_params_ts: uint256
max_price_increment: public(uint256) # precision 10**18
max_v2_duration: public(uint256) # number of periods(weeks)
@view
@external
def price_v1(_i: uint256 = 0) -> uint256:
"""
@notice Get approximate `scrvUSD.pricePerShare()`
@dev Price is simulated as if noone interacted to change `scrvUSD.pricePerShare()`,
need to adjust rate when too off.
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
"""
return self._price_v1() if _i == 0 else 10**36 // self._price_v1()
@view
def _price_v1() -> uint256:
return self._smoothed_price(
self.last_prices[1], self._raw_price(block.timestamp, self.price_params_ts)
)
@view
def _smoothed_price(last_price: uint256, raw_price: uint256) -> uint256:
# Ideally should be (max_price_increment / 10**18) **(block.timestamp - self.last_update)
# Using linear approximation to simplify calculations
max_change: uint256 = (
self.max_price_increment * (block.timestamp - self.last_update) * last_price // 10**18
)
# -max_change <= (raw_price - last_price) <= max_change
if unsafe_sub(raw_price + max_change, last_price) > 2 * max_change:
return last_price + max_change if raw_price > last_price else last_price - max_change
return raw_price
@view
@external
def raw_price(
_i: uint256 = 0, _ts: uint256 = block.timestamp, _parameters_ts: uint256 = block.timestamp
) -> uint256:
"""
@notice Get approximate `scrvUSD.pricePerShare()` without smoothening
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
@param _ts Timestamp at which to see price (only near period is supported)
"""
p: uint256 = self._raw_price(_ts, _parameters_ts)
return p if _i == 0 else 10**36 // p
▶Example▼
This example returns the approximate pricePerShare() or pricePerAsset().
ScrvusdOracleV2.price_v1(0)
# returns pricePerShare()
ScrvusdOracleV2.price_v1(1)
# returns pricePerAsset()
price_v2
ScrvusdOracleV2.price_v2(_i: uint256 = 0) -> uint256: viewGetter for the approximate share or asset price assuming constant rewards over time.
Returns: approximate pricePerShare() (uint256).
| Input | Type | Description |
|---|---|---|
_i | uint256 | 0 for pricePerShare() and 1 for pricePerAsset() |
<>Source code▼
struct PriceParams:
# assets
total_debt: uint256
total_idle: uint256
# supply
total_supply: uint256
full_profit_unlock_date: uint256
profit_unlocking_rate: uint256
last_profit_update: uint256
balance_of_self: uint256
last_block_number: public(uint256) # Warning: used both for price parameters and unlock_time
# smoothening
last_prices: uint256[3]
last_update: uint256
# scrvUSD replication parameters
profit_max_unlock_time: public(uint256)
price_params: PriceParams
price_params_ts: uint256
max_price_increment: public(uint256) # precision 10**18
max_v2_duration: public(uint256) # number of periods(weeks)
@view
@external
def price_v2(_i: uint256 = 0) -> uint256:
"""
@notice Get approximate `scrvUSD.pricePerShare()`
@dev Uses assumption that crvUSD gains same rewards.
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
"""
return self._price_v2() if _i == 0 else 10**36 // self._price_v2()
@view
def _price_v2() -> uint256:
return self._smoothed_price(
self.last_prices[2], self._raw_price(block.timestamp, block.timestamp)
)
@view
def _smoothed_price(last_price: uint256, raw_price: uint256) -> uint256:
# Ideally should be (max_price_increment / 10**18) **(block.timestamp - self.last_update)
# Using linear approximation to simplify calculations
max_change: uint256 = (
self.max_price_increment * (block.timestamp - self.last_update) * last_price // 10**18
)
# -max_change <= (raw_price - last_price) <= max_change
if unsafe_sub(raw_price + max_change, last_price) > 2 * max_change:
return last_price + max_change if raw_price > last_price else last_price - max_change
return raw_price
@view
@external
def raw_price(
_i: uint256 = 0, _ts: uint256 = block.timestamp, _parameters_ts: uint256 = block.timestamp
) -> uint256:
"""
@notice Get approximate `scrvUSD.pricePerShare()` without smoothening
@param _i 0 (default) for `pricePerShare()` and 1 for `pricePerAsset()`
@param _ts Timestamp at which to see price (only near period is supported)
"""
p: uint256 = self._raw_price(_ts, _parameters_ts)
return p if _i == 0 else 10**36 // p
▶Example▼
This example returns the approximate pricePerShare() or pricePerAsset() using the assumption that crvUSD gains same rewards.
ScrvusdOracleV2.price_v2(0)
# returns pricePerShare()
ScrvusdOracleV2.price_v2(1)
# returns pricePerAsset()
last_block_number
ScrvusdOracleV2.last_block_number() -> uint256: viewGetter for the block number corresponding to the most recent update applied to the oracle (either for the price or profit_max_unlock_time). This value is updated during calls to the update_price() function to ensure that only updates from the same or a later block are accepted to prevent outdated information from being used.
Returns: the last block number the oracle was updated (uint256).
<>Source code▼
last_block_number: public(uint256) # Warning: used both for price parameters and unlock_time
▶Example▼
This example returns the block number of the most recent update.
>>> ScrvusdOracleV2.last_block_number()
17153668
Adjustable Parameters
The oracle has the following adjustable parameters:
profit_max_unlock_time: period over which accrued profits are gradually unlocked to smooth the share price transition.max_price_increment: caps the maximum rate at which the share price can change per second to prevent abrupt price fluctuations.max_v2_duration: limits the number of periods used in the v2 price approximation, restricting how far future reward accrual is projected.
To guard the respective functions which can change the parameters, the contract uses a snekmate module with different roles.
profit_max_unlock_time
ScrvusdOracleV2.profit_max_unlock_time() -> uint256: viewGetter for the duration in seconds over which rewards are gradually unlocked, thereby smoothing out share price adjustments. It is initially set to one week (7 * 86400 seconds) to align with the current Yearn Vault setting and can only be updated by the VERIFIER role using the update_profit_max_unlock_time function.
Returns: profit max unlock time (uint256).
<>Source code▼
profit_max_unlock_time: public(uint256)
@deploy
def __init__(_initial_price: uint256):
"""
@param _initial_price Initial price of asset per share (10**18)
"""
...
self.profit_max_unlock_time = 7 * 86400 # Week by default
...
▶Example▼
This example returns the current profit_max_unlock_time.
>>> ScrvusdOracleV2.profit_max_unlock_time()
604800
update_profit_max_unlock_time
ScrvusdOracleV2.update_profit_max_unlock_time(_profit_max_unlock_time: uint256, _block_number: uint256) -> boolThis contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the UNLOCK_TIME_VERIFIER role.
Function to set a new value for profit_max_unlock_time. This happens within the ScrvUSDVeriferV2 contract when a period is verified using a block hash (verifyPeriodByBlockHash()).
Returns: boolean whether the value changed (bool).
| Input | Type | Description |
|---|---|---|
_profit_max_unlock_time | uint256 | New profit_max_unlock_time value |
_block_number | uint256 | Block number of parameters to linearize updates |
<>Source code▼
from snekmate.auth import access_control
initializes: access_control
exports: (
access_control.supportsInterface,
access_control.hasRole,
access_control.DEFAULT_ADMIN_ROLE,
access_control.grantRole,
access_control.revokeRole,
)
UNLOCK_TIME_VERIFIER: public(constant(bytes32)) = keccak256("UNLOCK_TIME_VERIFIER")
last_block_number: public(uint256) # Warning: used both for price parameters and unlock_time
profit_max_unlock_time: public(uint256)
@external
def update_profit_max_unlock_time(_profit_max_unlock_time: uint256, _block_number: uint256) -> bool:
"""
@notice Update price using `_parameters`
@param _profit_max_unlock_time New `profit_max_unlock_time` value
@param _block_number Block number of parameters to linearize updates
@return Boolean whether value changed
"""
access_control._check_role(UNLOCK_TIME_VERIFIER, msg.sender)
# Allowing same block updates for fixing bad blockhash provided (if possible)
assert self.last_block_number <= _block_number, "Outdated"
self.last_block_number = _block_number
prev_value: uint256 = self.profit_max_unlock_time
self.profit_max_unlock_time = _profit_max_unlock_time
return prev_value != _profit_max_unlock_time
▶Example▼
This example updates the profit_max_unlock_time value.
>>> ScrvusdOracleV2.profit_max_unlock_time()
604800
>>> ScrvusdOracleV2.update_profit_max_unlock_time(302400, todo)
>>> ScrvusdOracleV2.profit_max_unlock_time()
302400
max_price_increment
ScrvusdOracleV2.max_price_increment() -> uint256: viewGetter for the maximum allowed price increment per second for scrvusd, measured with a precision of . It is initially set to 2 * 1012 — corresponding to 0.02 bps per second (or approximately 0.24 bps per block on Ethereum) and linearly approximated to a maximum of 63% APY — and can be updated via the set_max_price_increment function.
Returns: max price increment per second (uint256).
<>Source code▼
max_price_increment: public(uint256) # precision 10**18
@deploy
def __init__(_initial_price: uint256):
"""
@param _initial_price Initial price of asset per share (10**18)
"""
...
# 2 * 10 **12 is equivalent to
# 1) 0.02 bps per second or 0.24 bps per block on Ethereum
# 2) linearly approximated to max 63% APY
self.max_price_increment = 2 * 10**12
....
▶Example▼
This example returns the maximum price increment per second of scrvusd.
>>> ScrvusdOracleV2.max_price_increment()
2000000000000
set_max_price_increment
ScrvusdOracleV2.set_max_price_increment(_max_price_increment: uint256)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the DEFAULT_ADMIN_ROLE role.
Function to set a new value for max_price_increment. The new value must be less than the stableswaps minimum fee.
\frac{fee}{2 * \text{block_time}} is considered to be safe.
Emits: SetMaxPriceIncrement event.
| Input | Type | Description |
|---|---|---|
_max_price_increment | uint256 | New max_price_increment value |
<>Source code▼
from snekmate.auth import access_control
initializes: access_control
exports: (
access_control.supportsInterface,
access_control.hasRole,
access_control.DEFAULT_ADMIN_ROLE,
access_control.grantRole,
access_control.revokeRole,
)
event SetMaxPriceIncrement:
max_acceleration: uint256
max_price_increment: public(uint256) # precision 10**18
@external
def set_max_price_increment(_max_price_increment: uint256):
"""
@notice Set maximum price increment of scrvUSD.
Must be less than StableSwap's minimum fee.
fee / (2 * block_time) is considered to be safe.
@param _max_price_increment Maximum acceleration (per sec)
"""
access_control._check_role(access_control.DEFAULT_ADMIN_ROLE, msg.sender)
assert 10**8 <= _max_price_increment and _max_price_increment <= 10**18
self.max_price_increment = _max_price_increment
log SetMaxPriceIncrement(_max_price_increment)
▶Example▼
This example updates the max_price_increment value.
>>> ScrvusdOracleV2.max_price_increment()
2000000000000
>>> ScrvusdOracleV2.set_max_price_increment(3000000000000)
>>> ScrvusdOracleV2.max_price_increment()
3000000000000
max_v2_duration
ScrvusdOracleV2.max_v2_duration() -> uint256: viewGetter for the maximum duration for which the price_v2 approximation can be applied before capping further growth. It is initially set to 24 weeks and can be updated via the set_max_v2_duration function.
Returns: max v2 duration (uint256).
<>Source code▼
max_v2_duration: public(uint256) # number of periods(weeks)
@deploy
def __init__(_initial_price: uint256):
"""
@param _initial_price Initial price of asset per share (10**18)
"""
...
self.max_v2_duration = 4 * 6 # half a year
...
▶Example▼
This example returns the max_v2_duration value.
>>> ScrvusdOracleV2.max_v2_duration()
24
set_max_v2_duration
ScrvusdOracleV2.set_max_v2_duration(_max_v2_duration: uint256)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the DEFAULT_ADMIN_ROLE role.
Function to set a new value for max_v2_duration. The new value must be less than MAX_V2_DURATION (4 years).
Emits: SetMaxV2Duration event.
| Input | Type | Description |
|---|---|---|
_max_v2_duration | uint256 | Maximum v2 approximation duration (in weeks) |
<>Source code▼
from snekmate.auth import access_control
initializes: access_control
exports: (
access_control.supportsInterface,
access_control.hasRole,
access_control.DEFAULT_ADMIN_ROLE,
access_control.grantRole,
access_control.revokeRole,
)
event SetMaxV2Duration:
max_v2_duration: uint256
MAX_V2_DURATION: constant(uint256) = 4 * 12 * 4 # 4 years
max_v2_duration: public(uint256) # number of periods(weeks)
@external
def set_max_v2_duration(_max_v2_duration: uint256):
"""
@notice Set maximum v2 approximation duration after which growth will be stopped.
@param _max_v2_duration Maximum v2 approximation duration (in number of periods)
"""
access_control._check_role(access_control.DEFAULT_ADMIN_ROLE, msg.sender)
assert _max_v2_duration <= MAX_V2_DURATION
self.max_v2_duration = _max_v2_duration
log SetMaxV2Duration(_max_v2_duration)
▶Example▼
This example updates the max_v2_duration value.
>>> ScrvusdOracleV2.max_v2_duration()
24
>>> ScrvusdOracleV2.set_max_v2_duration(26)
>>> ScrvusdOracleV2.max_v2_duration()
26
Snekmate Access Control
The contract makes use of the access_control.vy module for access control. More here.