-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathplatform_integration_test.cdc
More file actions
223 lines (175 loc) · 10 KB
/
platform_integration_test.cdc
File metadata and controls
223 lines (175 loc) · 10 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
import Test
import BlockchainHelpers
import "MOET"
import "test_helpers.cdc"
/*
Platform integration tests covering the path used by platforms using FlowALPv0 to create
and manage new positions. These tests currently only cover the happy path, ensuring that
transactions creating & updating positions succeed.
*/
access(all) var snapshot: UInt64 = 0
access(all)
fun setup() {
deployContracts()
snapshot = getCurrentBlockHeight()
}
access(all)
fun testDeploymentSucceeds() {
log("Success: contracts deployed")
}
access(all)
fun testCreatePoolSucceeds() {
createAndStorePool(signer: PROTOCOL_ACCOUNT, defaultTokenIdentifier: MOET_TOKEN_IDENTIFIER, beFailed: false)
let existsRes = _executeScript("../scripts/flow-alp/pool_exists.cdc", [PROTOCOL_ACCOUNT.address])
Test.expect(existsRes, Test.beSucceeded())
let exists = existsRes.returnValue as! Bool
Test.assert(exists)
}
access(all)
fun testCreateUserPositionSucceeds() {
Test.reset(to: snapshot)
// mock setup
setMockOraclePrice(signer: PROTOCOL_ACCOUNT, forTokenIdentifier: FLOW_TOKEN_IDENTIFIER, price: 1.0)
// create pool & add FLOW as supported token in globalLedger
createAndStorePool(signer: PROTOCOL_ACCOUNT, defaultTokenIdentifier: MOET_TOKEN_IDENTIFIER, beFailed: false)
addSupportedTokenZeroRateCurve(
signer: PROTOCOL_ACCOUNT,
tokenTypeIdentifier: FLOW_TOKEN_IDENTIFIER,
collateralFactor: 0.8,
borrowFactor: 1.0,
depositRate: 1_000_000.0,
depositCapacityCap: 1_000_000.0
)
let collateralAmount = 1_000.0 // FLOW
// configure user account
let user = Test.createAccount()
setupMoetVault(user, beFailed: false)
mintFlow(to: user, amount: collateralAmount)
// Grant beta access to user so they can create positions
grantBetaPoolParticipantAccess(PROTOCOL_ACCOUNT, user)
// ensure user does not have a MOET balance
var moetBalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)!
Test.assertEqual(0.0, moetBalance)
// ensure there is not yet a position open - fails as there are no open positions yet
getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: false, beFailed: true)
// open the position & push to drawDownSink - forces MOET to downstream test sink which is user's MOET Vault
let res = executeTransaction("../transactions/flow-alp/position/create_position.cdc",
[collateralAmount, FLOW_VAULT_STORAGE_PATH, true], // amount, vaultStoragePath, pushToDrawDownSink
user
)
Test.expect(res, Test.beSucceeded())
// ensure the position is now open
let pidZeroBalance = getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: false, beFailed: false)
Test.assert(pidZeroBalance > 0.0)
// ensure MOET has flown to the user's MOET Vault via the VaultSink provided when opening the position
moetBalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)!
Test.assert(moetBalance > 0.0)
}
access(all)
fun testUndercollateralizedPositionRebalanceSucceeds() {
Test.reset(to: snapshot)
let initialFlowPrice = 1.0 // initial price of FLOW set in the mock oracle
let priceChange = 0.2 // the percentage difference in the price of FLOW
// mock setup
setMockOraclePrice(signer: PROTOCOL_ACCOUNT, forTokenIdentifier: FLOW_TOKEN_IDENTIFIER, price: initialFlowPrice)
// create pool & add FLOW as supported token in globalLedger
createAndStorePool(signer: PROTOCOL_ACCOUNT, defaultTokenIdentifier: MOET_TOKEN_IDENTIFIER, beFailed: false)
addSupportedTokenZeroRateCurve(
signer: PROTOCOL_ACCOUNT,
tokenTypeIdentifier: FLOW_TOKEN_IDENTIFIER,
collateralFactor: 0.8,
borrowFactor: 1.0,
depositRate: 1_000_000.0,
depositCapacityCap: 1_000_000.0
)
let collateralAmount = 1_000.0 // FLOW used when opening the position
// configure user account
let user = Test.createAccount()
setupMoetVault(user, beFailed: false)
mintFlow(to: user, amount: collateralAmount)
// Grant beta access to user so they can create positions
grantBetaPoolParticipantAccess(PROTOCOL_ACCOUNT, user)
// open the position & push to drawDownSink - forces MOET to downstream test sink which is user's MOET Vault
let res = executeTransaction("../transactions/flow-alp/position/create_position.cdc",
[collateralAmount, FLOW_VAULT_STORAGE_PATH, true], // amount, vaultStoragePath, pushToDrawDownSink
user
)
Test.expect(res, Test.beSucceeded())
// check how much MOET the user has after borrowing
let moetBalanceBeforeRebalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)!
let availableBeforePriceChange = getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: false, beFailed: false)
let healthBeforePriceChange = getPositionHealth(pid: 0, beFailed: false)
// decrease the price of the collateral
setMockOraclePrice(signer: PROTOCOL_ACCOUNT, forTokenIdentifier: FLOW_TOKEN_IDENTIFIER, price: initialFlowPrice * (1.0 - priceChange))
let availableAfterPriceChange = getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: true, beFailed: false)
let healthAfterPriceChange = getPositionHealth(pid: 0, beFailed: false)
// rebalance should pull from the topUpSource, decreasing the MOET in the user's Vault since we use a VaultSource
// as a topUpSource when opening the Position
let rebalanceRes = rebalancePosition(signer: PROTOCOL_ACCOUNT, pid: 0, force: true)
Test.expect(rebalanceRes, Test.beSucceeded())
let moetBalanceAfterRebalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)!
let healthAfterRebalance = getPositionHealth(pid: 0, beFailed: false)
// NOTE - exact amounts are not tested here, this is purely a behavioral test though we may update these tests
// user's MOET vault balance decreases due to withdrawal by pool via topUpSource
Test.assert(moetBalanceBeforeRebalance > moetBalanceAfterRebalance)
// the amount available should decrease after the collateral value has decreased
Test.assert(availableBeforePriceChange < availableAfterPriceChange)
// the health should decrease after the collateral value has decreased
Test.assert(healthBeforePriceChange > healthAfterPriceChange)
// the health should increase after rebalancing from undercollateralized state
Test.assert(healthAfterPriceChange < healthAfterRebalance)
}
access(all)
fun testOvercollateralizedPositionRebalanceSucceeds() {
Test.reset(to: snapshot)
let initialFlowPrice = 1.0 // initial price of FLOW set in the mock oracle
let priceChange = 1.2 // the percentage difference in the price of FLOW
// mock setup
setMockOraclePrice(signer: PROTOCOL_ACCOUNT, forTokenIdentifier: FLOW_TOKEN_IDENTIFIER, price: initialFlowPrice)
// create pool & add FLOW as supported token in globalLedger
createAndStorePool(signer: PROTOCOL_ACCOUNT, defaultTokenIdentifier: MOET_TOKEN_IDENTIFIER, beFailed: false)
addSupportedTokenZeroRateCurve(
signer: PROTOCOL_ACCOUNT,
tokenTypeIdentifier: FLOW_TOKEN_IDENTIFIER,
collateralFactor: 0.8,
borrowFactor: 1.0,
depositRate: 1_000_000.0,
depositCapacityCap: 1_000_000.0
)
let collateralAmount = 1_000.0 // FLOW used when opening the position
// configure user account
let user = Test.createAccount()
setupMoetVault(user, beFailed: false)
mintFlow(to: user, amount: collateralAmount)
// Grant beta access to user so they can create positions
grantBetaPoolParticipantAccess(PROTOCOL_ACCOUNT, user)
// open the position & push to drawDownSink - forces MOET to downstream test sink which is user's MOET Vault
let res = executeTransaction("../transactions/flow-alp/position/create_position.cdc",
[collateralAmount, FLOW_VAULT_STORAGE_PATH, true], // amount, vaultStoragePath, pushToDrawDownSink
user
)
Test.expect(res, Test.beSucceeded())
// check how much MOET the user has after borrowing
let moetBalanceBeforeRebalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)!
let availableBeforePriceChange = getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: false, beFailed: false)
let healthBeforePriceChange = getPositionHealth(pid: 0, beFailed: false)
// decrease the price of the collateral
setMockOraclePrice(signer: PROTOCOL_ACCOUNT, forTokenIdentifier: FLOW_TOKEN_IDENTIFIER, price: initialFlowPrice * (priceChange))
let availableAfterPriceChange = getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: true, beFailed: false)
let healthAfterPriceChange = getPositionHealth(pid: 0, beFailed: false)
// rebalance should pull from the topUpSource, decreasing the MOET in the user's Vault since we use a VaultSource
// as a topUpSource when opening the Position
let rebalanceRes = rebalancePosition(signer: PROTOCOL_ACCOUNT, pid: 0, force: true)
Test.expect(rebalanceRes, Test.beSucceeded())
let moetBalanceAfterRebalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)!
let healthAfterRebalance = getPositionHealth(pid: 0, beFailed: false)
// NOTE - exact amounts are not tested here, this is purely a behavioral test though we may update these tests
// user's MOET vault balance increase due to deposit by pool to drawDownSink
Test.assert(moetBalanceBeforeRebalance < moetBalanceAfterRebalance)
// the amount available increase after the collateral value has increased
Test.assert(availableBeforePriceChange < availableAfterPriceChange)
// the health should increase after the collateral value has decreased
Test.assert(healthBeforePriceChange < healthAfterPriceChange)
// the health should decrease after rebalancing from overcollateralized state
Test.assert(healthAfterPriceChange > healthAfterRebalance)
}