DeploySEALED

?^█*▪▫!█●%■&▒@■▫╳╳◇&█╱●◆▫◆■^^?░~?&▫□%╲▪■□~╳!○╲~■●■~@○▒~$▫@$█◇◇●■

Transaction ID

Timestamp

Nov 13, 2025, 08:44:01 PM UTC
3mo ago

Block Height

132,673,007

Computation

0

Execution Fee

0.00000824 FLOW

Transaction Summary

Deploy

Contract deployment

Contract deployment

Script Arguments

0nameString
IncrementFiSwapperConnector
1codeString
import FungibleToken from 0xf233dcee88fe0abe import DeFiActions from 0x17ae3b1b0b0d50db import SwapRouter from 0xa6850776a94e6551 import SwapFactory from 0xb063c16cac85dbd1 /// IncrementFiSwapperConnector: FlowActions connector for Increment.fi DEX /// /// Implements Swapper interface for atomic swaps on Increment.fi /// /// SLIPPAGE PROTECTION: This connector returns RAW market data. Slippage protection /// is enforced at the caller layer (DCAVaultActions.executePurchaseWithSwapper) which: /// 1. Applies user-configured slippage tolerance to calculate minAmount /// 2. Passes minAmount to swap() which enforces it via SwapRouter.swapExactTokensForTokens /// 3. Validates actual slippage after execution against user's tolerance /// /// This separation allows users to configure slippage per DCA plan, rather than /// hardcoding a one-size-fits-all value in the connector. /// /// Official Documentation: https://docs.increment.fi /// access(all) contract IncrementFiSwapperConnector { /// Events access(all) event SwapExecuted( fromToken: String, toToken: String, amountIn: UFix64, amountOut: UFix64, pairAddress: Address ) /// IncrementFiSwapper resource implementing Swapper interface access(all) resource IncrementFiSwapper: DeFiActions.Swapper { access(all) let pairAddress: Address access(all) let routerAddress: Address access(all) let tokenKeyPath: [String] // Token identifiers for swap route init(pairAddress: Address, routerAddress: Address, tokenKeyPath: [String]) { self.pairAddress = pairAddress self.routerAddress = routerAddress self.tokenKeyPath = tokenKeyPath } /// Execute swap on Increment.fi with slippage protection /// /// Uses SwapRouter.swapExactTokensForTokens to execute the swap. /// SLIPPAGE PROTECTION: Enforced via quote.minAmount parameter, which is /// calculated by the caller (DCAVaultActions) based on user's slippageTolerance. /// The swap will revert if output < minAmount. /// access(all) fun swap( inVault: @{FungibleToken.Vault}, quote: DeFiActions.Quote ): @{FungibleToken.Vault} { pre { inVault.balance > 0.0: "Input vault must have balance" quote.minAmount > 0.0: "Minimum amount must be positive" quote.deadline != nil && quote.deadline! >= getCurrentBlock().timestamp: "Quote expired" } let amountIn = inVault.balance let fromTokenType = inVault.getType().identifier // Execute swap through Increment.fi SwapRouter let outVault <- SwapRouter.swapExactTokensForTokens( exactVaultIn: <-inVault, amountOutMin: quote.minAmount, tokenKeyPath: self.tokenKeyPath, deadline: quote.deadline! ) let amountOut = outVault.balance let toTokenType = outVault.getType().identifier // Emit swap event emit SwapExecuted( fromToken: fromTokenType, toToken: toTokenType, amountIn: amountIn, amountOut: amountOut, pairAddress: self.pairAddress ) return <-outVault } /// Get quote for swap - Returns RAW market data /// /// Queries Increment.fi SwapRouter for expected output amounts /// based on current pool reserves. /// /// SLIPPAGE PROTECTION DESIGN: /// This connector returns RAW market data (minAmount = expectedAmount). /// The CALLER is responsible for applying slippage protection by: /// 1. Reading their desired slippageTolerance from DCA plan configuration /// 2. Calculating: minAmount = expectedAmount * (1.0 - slippageTolerance) /// 3. Creating an adjusted Quote with the calculated minAmount /// 4. Passing that Quote to swap(), which enforces the minimum /// /// This design allows users to configure different slippage tolerances per /// DCA plan (e.g., 0.5% for stable pairs, 2% for volatile pairs). /// access(all) fun getQuote( fromTokenType: Type, toTokenType: Type, amount: UFix64 ): DeFiActions.Quote { // Query SwapRouter for expected amounts let amounts = SwapRouter.getAmountsOut( amountIn: amount, tokenKeyPath: self.tokenKeyPath ) // Last element is the expected output amount let expectedAmount = amounts[amounts.length - 1] // Return raw quote WITHOUT slippage applied // Caller should calculate minAmount based on their slippage tolerance // Example: minAmount = expectedAmount * (1.0 - slippageTolerance) return DeFiActions.Quote( expectedAmount: expectedAmount, minAmount: expectedAmount, // No slippage - caller applies their own slippageTolerance: 0.0, // Indicates no slippage applied by connector deadline: getCurrentBlock().timestamp + 300.0, // 5 minutes default data: { "pairAddress": self.pairAddress.toString(), "routerAddress": self.routerAddress.toString(), "tokenPath": self.tokenKeyPath.length.toString() } ) } /// Get swapper info access(all) fun getInfo(): DeFiActions.ComponentInfo { return DeFiActions.ComponentInfo( type: "Swapper", identifier: "IncrementFi", version: "1.0.0" ) } } /// Create IncrementFi swapper /// /// @param pairAddress: Address of the trading pair /// @param routerAddress: Address of SwapRouter contract /// Mainnet: 0xa6850776a94e6551 /// Testnet: 0x2f8af5ed05bbde0d /// @param tokenKeyPath: Array of token identifiers for swap route /// Format: ["A.{address}.{ContractName}", ...] /// Example: ["A.1654653399040a61.FlowToken", "A.f1ab99c82dee3526.USDCFlow"] /// access(all) fun createSwapper( pairAddress: Address, routerAddress: Address, tokenKeyPath: [String] ): @IncrementFiSwapper { pre { tokenKeyPath.length >= 2: "Token path must have at least 2 tokens" } return <- create IncrementFiSwapper( pairAddress: pairAddress, routerAddress: routerAddress, tokenKeyPath: tokenKeyPath ) } /// Helper to verify pair exists /// /// @param token0Key: First token identifier /// @param token1Key: Second token identifier /// @return Pair address if exists, nil otherwise /// access(all) fun getPairAddress(token0Key: String, token1Key: String): Address? { return SwapFactory.getPairAddress(token0Key: token0Key, token1Key: token1Key) } }

Cadence Script

1transaction(name: String, code: String ) {
2		prepare(signer: auth(AddContract) &Account) {
3			signer.contracts.add(name: name, code: code.utf8 )
4		}
5	}