This repository has been archived by the owner on Jul 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
/
UPayoffProvider.sol
75 lines (66 loc) · 3.32 KB
/
UPayoffProvider.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.13;
import "@equilibria/root/control/unstructured/UInitializable.sol";
import "@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol";
import "@equilibria/root/storage/UStorage.sol";
import "../interfaces/IPayoffProvider.sol";
import "../interfaces/types/PayoffDefinition.sol";
/**
* @title UPayoffProvider
* @notice Library for manage storing, surfacing, and upgrading a payoff provider.
* @dev Uses an unstructured storage pattern to store the oracle address and payoff definition which allows this
provider to be safely used with upgradeable contracts.
*/
abstract contract UPayoffProvider is IPayoffProvider, UInitializable {
/// @dev The oracle contract address
AddressStorage private constant _oracle =
AddressStorage.wrap(keccak256("equilibria.perennial.UPayoffProvider.oracle"));
function oracle() public view returns (IOracleProvider) { return IOracleProvider(_oracle.read()); }
/// @dev Payoff definition struct
PayoffDefinitionStorage private constant _payoffDefinition =
PayoffDefinitionStorage.wrap(keccak256("equilibria.perennial.UPayoffProvider.payoffDefinition"));
function payoffDefinition() public view returns (PayoffDefinition memory) { return _payoffDefinition.read(); }
/**
* @notice Initializes the contract state
* @param oracle_ Oracle address
* @param payoffDefinition_ Payoff provider
*/
// solhint-disable-next-line func-name-mixedcase
function __UPayoffProvider__initialize(IOracleProvider oracle_, PayoffDefinition calldata payoffDefinition_) internal onlyInitializer {
if (!Address.isContract(address(oracle_))) revert PayoffProviderInvalidOracle();
_oracle.store(address(oracle_));
if (!payoffDefinition_.valid()) revert PayoffProviderInvalidPayoffDefinitionError();
_payoffDefinition.store(payoffDefinition_);
}
/**
* @notice Returns the current oracle version transformed by the payoff definition
* @return Current oracle version transformed by the payoff definition
*/
function currentVersion() public view returns (IOracleProvider.OracleVersion memory) {
return _transform(oracle().currentVersion());
}
/**
* @notice Returns the oracle version at `oracleVersion` transformed by the payoff definition
* @param oracleVersion Oracle version to return for
* @return Oracle version at `oracleVersion` with price transformed by payoff function
*/
function atVersion(uint256 oracleVersion) public view returns (IOracleProvider.OracleVersion memory) {
return _transform(oracle().atVersion(oracleVersion));
}
/**
* @notice Yook to call sync() on the oracle provider and transform the resulting oracle version
*/
function _sync() internal returns (IOracleProvider.OracleVersion memory) {
return _transform(oracle().sync());
}
/**
* @notice Returns the transformed oracle version
* @param oracleVersion Oracle version to transform
* @return Transformed oracle version
*/
function _transform(IOracleProvider.OracleVersion memory oracleVersion)
internal view virtual returns (IOracleProvider.OracleVersion memory) {
oracleVersion.price = payoffDefinition().transform(oracleVersion.price);
return oracleVersion;
}
}