diff --git a/.github/workflows/cadence_tests.yml b/.github/workflows/cadence_tests.yml index d0fe6a17..918e0f41 100644 --- a/.github/workflows/cadence_tests.yml +++ b/.github/workflows/cadence_tests.yml @@ -33,9 +33,7 @@ jobs: path: ./imports key: flow-deps-${{ hashFiles('flow.json') }} - name: Install Flow CLI - env: - FLOW_CLI_VERSION: v2.7.2 - run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" + run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" -- v2.15.3 - name: Update PATH and show Flow version run: | echo "/root/.local/bin" >> $GITHUB_PATH @@ -45,7 +43,7 @@ jobs: - name: Install dependencies run: flow deps install --skip-alias --skip-deployments - name: Run tests - run: flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" ./cadence/tests/*_test.cdc + run: make ci - name: Upload coverage report uses: codecov/codecov-action@v5 with: diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..777982c6 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +.PHONY: test +test: + flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" ./cadence/tests/*_test.cdc + +.PHONY: lint +lint: + find cadence/contracts -name "*.cdc" | xargs flow cadence lint \ + | tee /dev/stderr | tail -n2 | grep -q "Lint passed" + +.PHONY: ci +ci: lint test diff --git a/cadence/contracts/FlowALPHealth.cdc b/cadence/contracts/FlowALPHealth.cdc index ee50c34d..45813648 100644 --- a/cadence/contracts/FlowALPHealth.cdc +++ b/cadence/contracts/FlowALPHealth.cdc @@ -168,7 +168,6 @@ access(all) contract FlowALPHealth { if potentialHealth >= targetHealth { // We can reach the target health by paying off some or all of the debt. We can easily // compute how many units of the token would be needed to reach the target health. - let healthChange = targetHealth - healthAfterWithdrawal let requiredEffectiveDebt = effectiveDebtAfterWithdrawal - (effectiveCollateralAfterWithdrawal / targetHealth) diff --git a/cadence/contracts/FlowALPInterestRates.cdc b/cadence/contracts/FlowALPInterestRates.cdc index 74819bd6..aa8ff0ae 100644 --- a/cadence/contracts/FlowALPInterestRates.cdc +++ b/cadence/contracts/FlowALPInterestRates.cdc @@ -34,7 +34,7 @@ access(all) contract FlowALPInterestRates { self.yearlyRate = yearlyRate } - access(all) fun interestRate(creditBalance: UFix128, debitBalance: UFix128): UFix128 { + access(all) fun interestRate(creditBalance _: UFix128, debitBalance _1: UFix128): UFix128 { return self.yearlyRate } } diff --git a/cadence/contracts/FlowALPModels.cdc b/cadence/contracts/FlowALPModels.cdc index 42f60eb5..67945e9a 100644 --- a/cadence/contracts/FlowALPModels.cdc +++ b/cadence/contracts/FlowALPModels.cdc @@ -812,7 +812,7 @@ access(all) contract FlowALPModels { /// Gets a swapper from the DEX for the given token pair. See PoolConfig.getSwapperForLiquidation. access(all) fun getSwapperForLiquidation(seizeType: Type, debtType: Type): {DeFiActions.Swapper} { return self.dex.getSwapper(inType: seizeType, outType: debtType) - ?? panic("No DEX swapper configured for liquidation pair: ".concat(seizeType.identifier).concat(" -> ").concat(debtType.identifier)) + ?? panic("No DEX swapper configured for liquidation pair: \(seizeType.identifier) -> \(debtType.identifier)") } // Setters @@ -2057,7 +2057,7 @@ access(all) contract FlowALPModels { /// Returns an authorized reference to the draw-down sink, or nil if none is configured. access(EImplementation) fun borrowDrawDownSink(): auth(FungibleToken.Withdraw) &{DeFiActions.Sink}? { - return &self.drawDownSink as auth(FungibleToken.Withdraw) &{DeFiActions.Sink}? + return &self.drawDownSink } /// Sets the draw-down sink. Sink must accept MOET deposits, or be nil. @@ -2073,7 +2073,7 @@ access(all) contract FlowALPModels { /// Returns an authorized reference to the top-up source, or nil if none is configured. access(EImplementation) fun borrowTopUpSource(): auth(FungibleToken.Withdraw) &{DeFiActions.Source}? { - return &self.topUpSource as auth(FungibleToken.Withdraw) &{DeFiActions.Source}? + return &self.topUpSource } /// Sets the top-up source. See InternalPosition.setTopUpSource. diff --git a/cadence/contracts/FlowALPPositionResources.cdc b/cadence/contracts/FlowALPPositionResources.cdc index ba406725..4a7404c5 100644 --- a/cadence/contracts/FlowALPPositionResources.cdc +++ b/cadence/contracts/FlowALPPositionResources.cdc @@ -106,7 +106,7 @@ access(all) contract FlowALPPositionResources { } /// Returns the maximum amount of the given token type that could be deposited into this position - access(all) fun getDepositCapacity(type: Type): UFix64 { + access(all) fun getDepositCapacity(type _: Type): UFix64 { // There's no limit on deposits from the position's perspective return UFix64.max } diff --git a/cadence/contracts/FlowALPRebalancerv1.cdc b/cadence/contracts/FlowALPRebalancerv1.cdc index 079b9602..7388cd44 100644 --- a/cadence/contracts/FlowALPRebalancerv1.cdc +++ b/cadence/contracts/FlowALPRebalancerv1.cdc @@ -96,7 +96,7 @@ access(all) contract FlowALPRebalancerv1 { txFunder: {DeFiActions.Sink, DeFiActions.Source} ) { pre { - interval > UInt64(0): + interval > 0: "Invalid interval: \(interval) - must be greater than 0" interval < UInt64(UFix64.max) - UInt64(getCurrentBlock().timestamp): "Invalid interval: \(interval) - must be less than the maximum interval of \(UInt64(UFix64.max) - UInt64(getCurrentBlock().timestamp))" @@ -171,7 +171,7 @@ access(all) contract FlowALPRebalancerv1 { /// @param id: The id of the scheduled transaction /// @param data: The data that was passed when the transaction was originally scheduled /// - access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) { + access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data _: AnyStruct?) { // we want to panic and not keep spending fees on scheduled transactions if borrow fails let positionRebalanceCap = self._positionRebalanceCapability.borrow()! positionRebalanceCap.rebalance(force: self.recurringConfig.getForceRebalance()) diff --git a/cadence/contracts/FlowALPSupervisorv1.cdc b/cadence/contracts/FlowALPSupervisorv1.cdc index 92468569..c8665ae1 100644 --- a/cadence/contracts/FlowALPSupervisorv1.cdc +++ b/cadence/contracts/FlowALPSupervisorv1.cdc @@ -47,7 +47,7 @@ access(all) contract FlowALPSupervisorv1 { /// Scheduler callback: on each tick, call fixReschedule on every registered paid rebalancer, /// recovering any that failed to schedule their next transaction. Stale UUIDs (rebalancer /// deleted without being removed from this set) are pruned automatically. - access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) { + access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data _: AnyStruct?) { emit Executed(id: id) for positionID in self.paidRebalancers.keys { let found = FlowALPRebalancerPaidv1.fixReschedule(positionID: positionID) diff --git a/cadence/contracts/FlowALPv0.cdc b/cadence/contracts/FlowALPv0.cdc index 224bf8e1..17aab380 100644 --- a/cadence/contracts/FlowALPv0.cdc +++ b/cadence/contracts/FlowALPv0.cdc @@ -755,7 +755,7 @@ access(all) contract FlowALPv0 { access(self) fun computeRequiredDepositForHealth( position: &{FlowALPModels.InternalPosition}, depositType: Type, - withdrawType: Type, + withdrawType _: Type, effectiveCollateral: UFix128, effectiveDebt: UFix128, targetHealth: UFix128 @@ -1030,7 +1030,6 @@ access(all) contract FlowALPv0 { // assign issuance & repayment connectors within the InternalPosition let iPos = self._borrowPosition(pid: id) - let fundsType = funds.getType() iPos.setDrawDownSink(issuanceSink) if repaymentSource != nil { iPos.setTopUpSource(repaymentSource) @@ -1044,14 +1043,7 @@ access(all) contract FlowALPv0 { self._rebalancePositionNoLock(pid: id, force: true) } - // Create a capability to the Pool for the Position resource - // The Pool is stored in the FlowALPv0 contract account - let poolCap = FlowALPv0.account.capabilities.storage.issue( - FlowALPv0.PoolStoragePath - ) - // Create and return the Position resource - let position <- FlowALPPositionResources.createPosition(id: id) self.unlockPosition(id) @@ -1402,7 +1394,7 @@ access(all) contract FlowALPv0 { /// Returns a mutable reference to the pool's configuration. /// Use this to update config fields that don't require events or side effects. access(FlowALPModels.EGovernance) fun borrowConfig(): auth(FlowALPModels.EImplementation) &{FlowALPModels.PoolConfig} { - return &self.config as auth(FlowALPModels.EImplementation) &{FlowALPModels.PoolConfig} + return &self.config } /// Pauses the pool, temporarily preventing further withdrawals, deposits, and liquidations @@ -2240,7 +2232,7 @@ access(all) contract FlowALPv0 { ) FlowALPv0.account.storage.save(<-pool, to: FlowALPv0.PoolStoragePath) let cap = FlowALPv0.account.capabilities.storage.issue<&Pool>(FlowALPv0.PoolStoragePath) - FlowALPv0.account.capabilities.unpublish(FlowALPv0.PoolPublicPath) + let _ = FlowALPv0.account.capabilities.unpublish(FlowALPv0.PoolPublicPath) FlowALPv0.account.capabilities.publish(cap, at: FlowALPv0.PoolPublicPath) } } @@ -2282,7 +2274,6 @@ access(all) contract FlowALPv0 { <-create PoolFactory(), to: self.PoolFactoryPath ) - let factory = self.account.storage.borrow<&PoolFactory>(from: self.PoolFactoryPath)! FlowALPPositionResources.setPoolCap(cap: self._borrowPool()) } } diff --git a/cadence/contracts/MOET.cdc b/cadence/contracts/MOET.cdc index edc666f9..06389587 100644 --- a/cadence/contracts/MOET.cdc +++ b/cadence/contracts/MOET.cdc @@ -25,11 +25,11 @@ access(all) contract MOET : FungibleToken { /// and store the returned Vault in their storage in order to allow their /// account to be able to receive deposits of this token type. /// - access(all) fun createEmptyVault(vaultType: Type): @MOET.Vault { + access(all) fun createEmptyVault(vaultType _: Type): @MOET.Vault { return <- create Vault(balance: 0.0) } - access(all) view fun getContractViews(resourceType: Type?): [Type] { + access(all) view fun getContractViews(resourceType _: Type?): [Type] { return [ Type(), Type(), @@ -38,7 +38,7 @@ access(all) contract MOET : FungibleToken { ] } - access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? { + access(all) fun resolveContractView(resourceType _: Type?, viewType: Type): AnyStruct? { switch viewType { case Type(): return FungibleTokenMetadataViews.FTView( diff --git a/cadence/contracts/PriceOracleAggregatorv1.cdc b/cadence/contracts/PriceOracleAggregatorv1.cdc index d7036843..eaa2ad4f 100644 --- a/cadence/contracts/PriceOracleAggregatorv1.cdc +++ b/cadence/contracts/PriceOracleAggregatorv1.cdc @@ -340,7 +340,7 @@ access(all) contract PriceOracleAggregatorv1 { } /// Function called by the scheduler to update the price history. - access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) { + access(FlowTransactionScheduler.Execute) fun executeTransaction(id _: UInt64, data _1: AnyStruct?) { let priceOracleAggregator = self.borrowPriceOracleAggregator() priceOracleAggregator.tryAddPriceToHistory() } diff --git a/cadence/contracts/mocks/DummyConnectors.cdc b/cadence/contracts/mocks/DummyConnectors.cdc index d72f62b3..8a7a8b1c 100644 --- a/cadence/contracts/mocks/DummyConnectors.cdc +++ b/cadence/contracts/mocks/DummyConnectors.cdc @@ -22,7 +22,7 @@ access(all) contract DummyConnectors { return UFix64.max } - access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { + access(all) fun depositCapacity(from _: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { // no-op } diff --git a/cadence/contracts/mocks/MockDexSwapper.cdc b/cadence/contracts/mocks/MockDexSwapper.cdc index ab692d70..0601f1cf 100644 --- a/cadence/contracts/mocks/MockDexSwapper.cdc +++ b/cadence/contracts/mocks/MockDexSwapper.cdc @@ -46,7 +46,7 @@ access(all) contract MockDexSwapper { /// Panics if no swapper for the given pair exists. access(all) fun removeMockDEXSwapperForPair(inType: Type, outType: Type) { let swappersForInTypeRef = &self.swappers[inType]! as auth(Mutate) &{Type: Swapper} - swappersForInTypeRef.remove(key: outType) + let _ = swappersForInTypeRef.remove(key: outType) } access(all) struct BasicQuote : DeFiActions.Quote { @@ -117,7 +117,7 @@ access(all) contract MockDexSwapper { return <- src.withdraw(amount: outAmt) } - access(all) fun swapBack(quote: {DeFiActions.Quote}?, residual: @{FungibleToken.Vault}): @{FungibleToken.Vault} { + access(all) fun swapBack(quote _: {DeFiActions.Quote}?, residual: @{FungibleToken.Vault}): @{FungibleToken.Vault} { // Not needed in tests; burn residual and panic to surface misuse Burner.burn(<-residual) panic("MockSwapper.swapBack() not implemented") diff --git a/cadence/contracts/mocks/MockYieldToken.cdc b/cadence/contracts/mocks/MockYieldToken.cdc index e5381918..e8659b17 100644 --- a/cadence/contracts/mocks/MockYieldToken.cdc +++ b/cadence/contracts/mocks/MockYieldToken.cdc @@ -29,11 +29,11 @@ access(all) contract MockYieldToken : FungibleToken { /// and store the returned Vault in their storage in order to allow their /// account to be able to receive deposits of this token type. /// - access(all) fun createEmptyVault(vaultType: Type): @MockYieldToken.Vault { + access(all) fun createEmptyVault(vaultType _: Type): @MockYieldToken.Vault { return <- create Vault(balance: 0.0) } - access(all) view fun getContractViews(resourceType: Type?): [Type] { + access(all) view fun getContractViews(resourceType _: Type?): [Type] { return [ Type(), Type(), @@ -42,7 +42,7 @@ access(all) contract MockYieldToken : FungibleToken { ] } - access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? { + access(all) fun resolveContractView(resourceType _: Type?, viewType: Type): AnyStruct? { switch viewType { case Type(): return FungibleTokenMetadataViews.FTView(