-
Notifications
You must be signed in to change notification settings - Fork 0
Recreate scenario 1 using fork testing setup. #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
RZhang05
wants to merge
18
commits into
main
Choose a base branch
from
raymond/forked-scen1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
e1007b2
Recreate scenario 1 using forked testnet.
RZhang05 351578c
Remove unused function.
RZhang05 5ff2bd0
Update for mainnet addresses.
RZhang05 3068055
Use mUSDC strategy with real oracles on testnet.
RZhang05 deb846e
Update symbol prices.
RZhang05 f197957
Switch to mainnet.
RZhang05 a719c67
Merge branch 'main' into raymond/forked-scen1
RZhang05 63dcad8
pyusd strategy
nialexsan dc00223
config transaction scripts
nialexsan d52baf9
Add option to transfer flow from whale account instead of minting.
RZhang05 54e0251
Merge branch 'main' into nialexsan/pyusd-fyv-strategy
nialexsan 4dc9664
mainnet setup script fixes
nialexsan f885957
add readme addresses
nialexsan 44a77a6
Merge branch 'nialexsan/pyusd-fyv-strategy' into raymond/forked-scen1
RZhang05 0d6b270
Use fixed mainnet height, new FUSDEV strategy.
RZhang05 2e2400c
Add percent tolerance check to forked test.
RZhang05 fc67c98
Clean up forked scenario 1.
RZhang05 f2ea7b3
Remove unnecessary imports.
RZhang05 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| // this height guarantees enough liquidity for the test | ||
| #test_fork(network: "mainnet", height: 140164761) | ||
|
|
||
| import Test | ||
| import BlockchainHelpers | ||
|
|
||
| import "test_helpers.cdc" | ||
|
|
||
| // FlowYieldVaults platform | ||
| import "FlowYieldVaults" | ||
| // other | ||
| import "FlowToken" | ||
| import "MOET" | ||
| import "FlowYieldVaultsStrategiesV1_1" | ||
| import "FlowCreditMarket" | ||
|
|
||
|
|
||
| // check (and update) flow.json for correct addresses | ||
| // mainnet addresses | ||
| access(all) let flowYieldVaultsAccount = Test.getAccount(0xb1d63873c3cc9f79) | ||
| access(all) let yieldTokenAccount = Test.getAccount(0xb1d63873c3cc9f79) | ||
| access(all) let flowCreditMarketAccount = Test.getAccount(0x6b00ff876c299c61) | ||
| access(all) let bandOracleAccount = Test.getAccount(0x6801a6222ebf784a) | ||
| access(all) let whaleFlowAccount = Test.getAccount(0x92674150c9213fc9) | ||
|
|
||
| access(all) var strategyIdentifier = Type<@FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy>().identifier | ||
| access(all) var flowTokenIdentifier = Type<@FlowToken.Vault>().identifier | ||
| access(all) var moetTokenIdentifier = Type<@MOET.Vault>().identifier | ||
|
|
||
| access(all) let collateralFactor = 0.8 | ||
| access(all) let targetHealthFactor = 1.3 | ||
|
|
||
| access(all) var snapshot: UInt64 = 0 | ||
|
|
||
| access(all) | ||
| fun setup() { | ||
| // BandOracle is only used for FLOW price for FCM collateral | ||
| let symbolPrices: {String: UFix64} = { | ||
| "FLOW": 1.0 | ||
| } | ||
| setBandOraclePrices(signer: bandOracleAccount, symbolPrices: symbolPrices) | ||
|
|
||
| let reserveAmount = 100_000_00.0 | ||
| // service account does not have enough flow to "mint" | ||
| // var mintFlowResult = mintFlow(to: flowCreditMarketAccount, amount: reserveAmount) | ||
| // Test.expect(mintFlowResult, Test.beSucceeded()) | ||
| transferFlow(signer: whaleFlowAccount, recipient: flowCreditMarketAccount.address, amount: reserveAmount) | ||
|
|
||
| mintMoet(signer: flowCreditMarketAccount, to: flowCreditMarketAccount.address, amount: reserveAmount, beFailed: false) | ||
|
|
||
| // Fund FlowYieldVaults account for scheduling fees (atomic initial scheduling) | ||
| // service account does not have enough flow to "mint" | ||
| // mintFlowResult = mintFlow(to: flowYieldVaultsAccount, amount: 100.0) | ||
| // Test.expect(mintFlowResult, Test.beSucceeded()) | ||
| transferFlow(signer: whaleFlowAccount, recipient: flowYieldVaultsAccount.address, amount: 100.0) | ||
| } | ||
|
|
||
| access(all) var testSnapshot: UInt64 = 0 | ||
| access(all) | ||
| fun test_ForkedRebalanceYieldVaultScenario1() { | ||
| let fundingAmount = 1000.0 | ||
|
|
||
| let user = Test.createAccount() | ||
|
|
||
| let flowPrices = [0.5, 0.8, 1.0, 1.2, 1.5, 2.0, 3.0, 5.0] | ||
|
|
||
| // Expected values from Google sheet calculations | ||
| let expectedYieldTokenValues: {UFix64: UFix64} = { | ||
| 0.5: 307.69230769, | ||
| 0.8: 492.30769231, | ||
| 1.0: 615.38461538, | ||
| 1.2: 738.46153846, | ||
| 1.5: 923.07692308, | ||
| 2.0: 1230.76923077, | ||
| 3.0: 1846.15384615, | ||
| 5.0: 3076.92307692 | ||
| } | ||
|
|
||
| // Likely 0.0 | ||
| let flowBalanceBefore = getBalance(address: user.address, vaultPublicPath: /public/flowTokenReceiver)! | ||
| // service account does not have enough flow to "mint" | ||
| // let mintFlowResult =The code snippet `mintFlow(to: user, amount: fundingAmount)` is a function call that mints a specified amount of a token (in this case, Flow tokens) to a specific user account. | ||
| // mintFlow(to: user, amount: fundingAmount) | ||
| // Test.expect(mintFlowResult, Test.beSucceeded()) | ||
| transferFlow(signer: whaleFlowAccount, recipient: user.address, amount: fundingAmount) | ||
| grantBeta(flowYieldVaultsAccount, user) | ||
|
|
||
| createYieldVault( | ||
| signer: user, | ||
| strategyIdentifier: strategyIdentifier, | ||
| vaultIdentifier: flowTokenIdentifier, | ||
| amount: fundingAmount, | ||
| beFailed: false | ||
| ) | ||
|
|
||
| // Capture the actual position ID from the FlowCreditMarket.Opened event | ||
| var pid = (getLastPositionOpenedEvent(Test.eventsOfType(Type<FlowCreditMarket.Opened>())) as! FlowCreditMarket.Opened).pid | ||
| log("[TEST] Captured Position ID from event: \(pid)") | ||
|
|
||
| var yieldVaultIDs = getYieldVaultIDs(address: user.address) | ||
| log("[TEST] YieldVault ID: \(yieldVaultIDs![0])") | ||
| Test.assert(yieldVaultIDs != nil, message: "Expected user's YieldVault IDs to be non-nil but encountered nil") | ||
| Test.assertEqual(1, yieldVaultIDs!.length) | ||
|
|
||
| var yieldVaultBalance = getYieldVaultBalance(address: user.address, yieldVaultID: yieldVaultIDs![0]) | ||
|
|
||
| log("[TEST] Initial yield vault balance: \(yieldVaultBalance ?? 0.0)") | ||
|
|
||
| rebalanceYieldVault(signer: flowYieldVaultsAccount, id: yieldVaultIDs![0], force: true, beFailed: false) | ||
| rebalancePosition(signer: flowCreditMarketAccount, pid: pid, force: true, beFailed: false) | ||
|
|
||
| testSnapshot = getCurrentBlockHeight() | ||
|
|
||
| for flowPrice in flowPrices { | ||
| if (getCurrentBlockHeight() > testSnapshot) { | ||
| Test.reset(to: testSnapshot) | ||
| } | ||
| yieldVaultBalance = getYieldVaultBalance(address: user.address, yieldVaultID: yieldVaultIDs![0]) | ||
|
|
||
| log("[TEST] YieldVault balance before flow price \(flowPrice) \(yieldVaultBalance ?? 0.0)") | ||
|
|
||
| setBandOraclePrice(signer: bandOracleAccount, symbol: "FLOW", price: flowPrice) | ||
|
|
||
| yieldVaultBalance = getYieldVaultBalance(address: user.address, yieldVaultID: yieldVaultIDs![0]) | ||
|
|
||
| log("[TEST] YieldVault balance before flow price \(flowPrice) rebalance: \(yieldVaultBalance ?? 0.0)") | ||
|
|
||
| // Get yield token balance before rebalance | ||
| let yieldTokensBefore = getAutoBalancerBalance(id: yieldVaultIDs![0]) ?? 0.0 | ||
| let currentValueBefore = getAutoBalancerCurrentValue(id: yieldVaultIDs![0]) ?? 0.0 | ||
|
|
||
| rebalanceYieldVault(signer: flowYieldVaultsAccount, id: yieldVaultIDs![0], force: false, beFailed: false) | ||
| rebalancePosition(signer: flowCreditMarketAccount, pid: pid, force: false, beFailed: false) | ||
|
|
||
| yieldVaultBalance = getYieldVaultBalance(address: user.address, yieldVaultID: yieldVaultIDs![0]) | ||
|
|
||
| log("[TEST] YieldVault balance after flow before \(flowPrice): \(yieldVaultBalance ?? 0.0)") | ||
|
|
||
| // Get yield token balance after rebalance | ||
| let yieldTokensAfter = getAutoBalancerBalance(id: yieldVaultIDs![0]) ?? 0.0 | ||
| let currentValueAfter = getAutoBalancerCurrentValue(id: yieldVaultIDs![0]) ?? 0.0 | ||
|
|
||
| // Get expected yield tokens from Google sheet calculations | ||
| let expectedYieldTokens = expectedYieldTokenValues[flowPrice] ?? 0.0 | ||
|
|
||
| log("\n=== SCENARIO 1 DETAILS for Flow Price \(flowPrice) ===") | ||
| log("YieldVault Balance: \(yieldVaultBalance ?? 0.0)") | ||
| log("Yield Tokens Before: \(yieldTokensBefore)") | ||
| log("Yield Tokens After: \(yieldTokensAfter)") | ||
| log("Expected Yield Tokens: \(expectedYieldTokens)") | ||
| let precisionDiff = yieldTokensAfter > expectedYieldTokens ? yieldTokensAfter - expectedYieldTokens : expectedYieldTokens - yieldTokensAfter | ||
| let precisionSign = yieldTokensAfter > expectedYieldTokens ? "+" : "-" | ||
| log("Precision Difference: \(precisionSign)\(precisionDiff)") | ||
| let percentDiff = expectedYieldTokens > 0.0 ? (precisionDiff / expectedYieldTokens) * 100.0 : 0.0 | ||
| log("Percent Difference: \(precisionSign)\(percentDiff)%") | ||
|
|
||
| // check if percent difference is within tolerance | ||
| let percentToleranceCheck = equalAmounts(a: percentDiff, b: 0.0, tolerance: forkedPercentTolerance) | ||
| Test.assert(percentToleranceCheck, message: "Percent difference \(percentDiff)% is not within tolerance \(forkedPercentTolerance)%") | ||
| log("Percent difference \(percentDiff)% is within tolerance \(forkedPercentTolerance)%") | ||
|
|
||
| let yieldChange = yieldTokensAfter > yieldTokensBefore ? yieldTokensAfter - yieldTokensBefore : yieldTokensBefore - yieldTokensAfter | ||
| let yieldSign = yieldTokensAfter > yieldTokensBefore ? "+" : "-" | ||
| log("Yield Token Change: \(yieldSign)\(yieldChange)") | ||
| log("Current Value Before: \(currentValueBefore)") | ||
| log("Current Value After: \(currentValueAfter)") | ||
| let valueChange = currentValueAfter > currentValueBefore ? currentValueAfter - currentValueBefore : currentValueBefore - currentValueAfter | ||
| let valueSign = currentValueAfter > currentValueBefore ? "+" : "-" | ||
| log("Value Change: \(valueSign)\(valueChange)") | ||
| log("=============================================\n") | ||
| } | ||
|
|
||
| closeYieldVault(signer: user, id: yieldVaultIDs![0], beFailed: false) | ||
|
|
||
| let flowBalanceAfter = getBalance(address: user.address, vaultPublicPath: /public/flowTokenReceiver)! | ||
| log("[TEST] flow balance after \(flowBalanceAfter)") | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
expectedYieldTokenValuesare the debt notional (at target health factor) in the unit of account i.e MOET/USD:expectedYieldTokenValue = expectedDebt = fundingAmount * flowPrice * collateralFactor / targetHealthFactor. It doesn't not account for the fees associated with swapping (nor price impact) MOET to yieldToken on the DEX when we create the yieldVault (ie.yieldToMoetSwapperin thecreateStrategy), as a consequence:expectedYieldTokenValue < expectedDebt.The bridge fees are in FLOW and covered by the protocol.