Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions cadence/tests/external_oracle_test.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#test_fork(network: "mainnet", height: nil)

import Test

import "FlowToken"
import "MOET"
import "EVMVMBridgedToken_99af3eea856556646c98c8b9b2548fe815240750" // PYUSD0

access(all) let PYUSD0VaultType = Type<@EVMVMBridgedToken_99af3eea856556646c98c8b9b2548fe815240750.Vault>()

access(all) fun setup() {
var err: Test.Error? = nil

// TODO(holyfuchs):
// remove this once this is deployed to mainnet: holyfuchs/incrementfi-price-oracle
err = Test.deployContract(
name: "IncrementFiSwapConnectors",
path: "../../FlowActions/cadence/contracts/connectors/increment-fi/IncrementFiSwapConnectors.cdc",
arguments: []
)
Test.expect(err, Test.beNil())
}

access(all) fun test_band() {
let feeAccount = Test.createAccount()
let txn = Test.Transaction(
code: Test.readFile("transactions/external_oracle/create_band_empty_fee.cdc"),
authorizers: [feeAccount.address],
signers: [feeAccount],
arguments: [Type<@MOET.Vault>()]
)
let result = Test.executeTransaction(txn)
Test.expect(result, Test.beSucceeded())

let unitScriptResult = Test.executeScript(
Test.readFile("scripts/external_oracle/band_unit_of_account.cdc"),
[feeAccount.address]
)
Test.expect(unitScriptResult, Test.beSucceeded())
let unitId = unitScriptResult.returnValue! as! String?
log(unitId)
Test.assert(unitId != nil, message: "expected unitOfAccount identifier")
Test.assert(unitId!.length > 0, message: "expected non-empty unitOfAccount")
}

access(all) fun test_band_price() {
let feeAccount = Test.createAccount()
let txn = Test.Transaction(
code: Test.readFile("transactions/external_oracle/create_band_empty_fee.cdc"),
authorizers: [feeAccount.address],
signers: [feeAccount],
arguments: [Type<@MOET.Vault>()]
)
Test.expect(Test.executeTransaction(txn), Test.beSucceeded())

let priceScriptResult = Test.executeScript(
Test.readFile("scripts/external_oracle/band_price.cdc"),
[feeAccount.address, Type<@FlowToken.Vault>()]
)
Test.expect(priceScriptResult, Test.beSucceeded())
let price = priceScriptResult.returnValue as! UFix64?
log(price)
Test.assert(price != nil, message: "expected price, got nil")
}

access(all) fun test_increment_fi() {
let flowKey = String.join(Type<@FlowToken.Vault>().identifier.split(separator: ".").slice(from: 0, upTo: 3), separator: ".")
let moetKey = String.join(Type<@MOET.Vault>().identifier.split(separator: ".").slice(from: 0, upTo: 3), separator: ".")
let path = [flowKey, moetKey]
let unitScriptResult = Test.executeScript(
Test.readFile("scripts/external_oracle/increment_fi_unit_of_account.cdc"),
[Type<@MOET.Vault>(), Type<@FlowToken.Vault>(), path]
)
Test.expect(unitScriptResult, Test.beSucceeded())
let unitId = unitScriptResult.returnValue! as! String?
Test.assert(unitId != nil, message: "expected unitOfAccount identifier")
Test.assert(unitId!.length > 0, message: "expected non-empty unitOfAccount")
}

access(all) fun test_increment_fi_price() {
let flowKey = String.join(Type<@FlowToken.Vault>().identifier.split(separator: ".").slice(from: 0, upTo: 3), separator: ".")
let pyusd0Key = String.join(PYUSD0VaultType.identifier.split(separator: ".").slice(from: 0, upTo: 3), separator: ".")
let path = [flowKey, pyusd0Key]
let priceScriptResult = Test.executeScript(
Test.readFile("scripts/external_oracle/increment_fi_price.cdc"),
[PYUSD0VaultType, Type<@FlowToken.Vault>(), path]
)
Test.expect(priceScriptResult, Test.beSucceeded())
let price = priceScriptResult.returnValue as! UFix64?
log(price)
Test.assert(price != nil, message: "expected price when pair exists")
}

12 changes: 12 additions & 0 deletions cadence/tests/scripts/external_oracle/band_price.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import "DeFiActions"

/// Borrows the Band oracle as DeFiActions.PriceOracle at
/// /public/bandOraclePriceOracle (created by create_band_empty_fee.cdc)
/// and returns the price of the given token type.
access(all) fun main(ownerAddress: Address, ofToken: Type): UFix64? {
let oracleRef = getAccount(ownerAddress).capabilities.borrow<&{DeFiActions.PriceOracle}>(/public/bandOraclePriceOracle)
if oracleRef == nil {
return nil
}
return oracleRef!.price(ofToken: ofToken)
}
12 changes: 12 additions & 0 deletions cadence/tests/scripts/external_oracle/band_unit_of_account.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import "DeFiActions"

/// Borrows the Band oracle as DeFiActions.PriceOracle at
/// /public/bandOraclePriceOracle (created by create_band_empty_fee.cdc)
/// and returns the unitOfAccount type identifier.
access(all) fun main(ownerAddress: Address): String? {
let oracleRef = getAccount(ownerAddress).capabilities.borrow<&{DeFiActions.PriceOracle}>(/public/bandOraclePriceOracle)
if oracleRef == nil {
return nil
}
return oracleRef!.unitOfAccount().identifier
}
15 changes: 15 additions & 0 deletions cadence/tests/scripts/external_oracle/increment_fi_price.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import "DeFiActions"
import "IncrementFiSwapConnectors"

/// Builds a DeFiActions.PriceOracle using IncrementFiSwapConnectors.PriceOracle
/// and returns price(ofToken: FLOW).
access(all) fun main(unitOfAccount: Type, baseToken: Type, path: [String]): UFix64? {
let oracle = IncrementFiSwapConnectors.PriceOracle(
unitOfAccount: unitOfAccount,
baseToken: baseToken,
path: path,
uniqueID: nil
)
let price = oracle.price(ofToken: baseToken)
return price
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import "DeFiActions"
import "FlowToken"
import "USDCFlow"
import "IncrementFiSwapConnectors"

/// Builds a DeFiActions.PriceOracle using IncrementFiSwapConnectors.PriceOracle
/// and returns the unitOfAccount identifier
access(all) fun main(unitOfAccount: Type, baseToken: Type, path: [String]): String? {
let oracle = IncrementFiSwapConnectors.PriceOracle(
unitOfAccount: unitOfAccount,
baseToken: baseToken,
path: path,
uniqueID: nil
)
return oracle.unitOfAccount().identifier
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import "FungibleToken"
import "FlowToken"
import "FungibleTokenConnectors"
import "BandOracleConnectors"

/// Creates a BandOracleConnectors.PriceOracle with the given unitOfAccount and
/// an empty FlowToken vault as the fee source, saves it to storage, and
/// publishes a capability at /public/bandOraclePriceOracle
transaction(unitOfAccount: Type) {
prepare(signer: auth(BorrowValue, SaveValue, Capabilities, IssueStorageCapabilityController, PublishCapability) &Account) {
let flowTokenAccount = getAccount(Type<@FlowToken.Vault>().address!)
let flowTokenRef = flowTokenAccount.contracts.borrow<&{FungibleToken}>(name: "FlowToken")
?? panic("FlowToken contract not found")
let emptyVault <- flowTokenRef.createEmptyVault(vaultType: Type<@FlowToken.Vault>())
signer.storage.save(<-emptyVault, to: /storage/flowFeeVault)

let cap = signer.capabilities.storage.issue<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(/storage/flowFeeVault)
let feeSource = FungibleTokenConnectors.VaultSource(min: nil, withdrawVault: cap, uniqueID: nil)
let oracle = BandOracleConnectors.PriceOracle(
unitOfAccount: unitOfAccount,
staleThreshold: 3600,
feeSource: feeSource,
uniqueID: nil
)
signer.storage.save(oracle, to: /storage/bandOraclePriceOracle)
let oracleCap = signer.capabilities.storage.issue<&BandOracleConnectors.PriceOracle>(/storage/bandOraclePriceOracle)
signer.capabilities.publish(oracleCap, at: /public/bandOraclePriceOracle)
}
}
Loading