-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathCryptoFromPoolArbitrum.vy
97 lines (79 loc) · 2.61 KB
/
CryptoFromPoolArbitrum.vy
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# @version 0.3.10
"""
@title CryptoFromPool
@notice Price oracle for pools which contain cryptos and crvUSD. This is NOT suitable for minted crvUSD - only for lent out
The oracle accounts for L2 downtimes using Chainlink uptime oracle:
https://docs.chain.link/data-feeds/l2-sequencer-feeds
@author Curve.Fi
@license MIT
"""
interface Pool:
def price_oracle(i: uint256 = 0) -> uint256: view # Universal method!
interface ChainlinkOracle:
def latestRoundData() -> ChainlinkAnswer: view
struct ChainlinkAnswer:
roundID: uint80
answer: int256
startedAt: uint256
updatedAt: uint256
answeredInRound: uint80
POOL: public(immutable(Pool))
BORROWED_IX: public(immutable(uint256))
COLLATERAL_IX: public(immutable(uint256))
N_COINS: public(immutable(uint256))
NO_ARGUMENT: public(immutable(bool))
CHAINLINK_UPTIME_FEED: public(constant(address)) = 0xFdB631F5EE196F0ed6FAa767959853A9F217697D
DOWNTIME_WAIT: public(constant(uint256)) = 3988 # 866 * log(100) s
@external
def __init__(
pool: Pool,
N: uint256,
borrowed_ix: uint256,
collateral_ix: uint256
):
assert borrowed_ix != collateral_ix
assert borrowed_ix < N
assert collateral_ix < N
POOL = pool
N_COINS = N
BORROWED_IX = borrowed_ix
COLLATERAL_IX = collateral_ix
no_argument: bool = False
if N == 2:
success: bool = False
res: Bytes[32] = empty(Bytes[32])
success, res = raw_call(
pool.address,
_abi_encode(empty(uint256), method_id=method_id("price_oracle(uint256)")),
max_outsize=32, is_static_call=True, revert_on_failure=False)
if not success:
no_argument = True
NO_ARGUMENT = no_argument
@internal
@view
def _raw_price() -> uint256:
# Check that we had no downtime
cl_answer: ChainlinkAnswer = ChainlinkOracle(CHAINLINK_UPTIME_FEED).latestRoundData()
assert cl_answer.answer == 0, "Sequencer is down"
assert block.timestamp >= cl_answer.startedAt + DOWNTIME_WAIT, "Wait after downtime"
p_borrowed: uint256 = 10**18
p_collateral: uint256 = 10**18
if NO_ARGUMENT:
p: uint256 = POOL.price_oracle()
if COLLATERAL_IX > 0:
p_collateral = p
else:
p_borrowed = p
else:
if BORROWED_IX > 0:
p_borrowed = POOL.price_oracle(BORROWED_IX - 1)
if COLLATERAL_IX > 0:
p_collateral = POOL.price_oracle(COLLATERAL_IX - 1)
return p_collateral * 10**18 / p_borrowed
@external
@view
def price() -> uint256:
return self._raw_price()
@external
def price_w() -> uint256:
return self._raw_price()