Smart Contract

DCATransactionHandlerEVMSimple

A.ca7ee55e4fc3251a.DCATransactionHandlerEVMSimple

Valid From

135,623,850

Deployed

5d ago
Feb 23, 2026, 12:44:34 AM UTC

Dependents

1 imports
1import FlowTransactionScheduler from 0xe467b9dd11fa00df
2import DCAControllerUnified from 0xca7ee55e4fc3251a
3import DCAPlanUnified from 0xca7ee55e4fc3251a
4import FungibleToken from 0xf233dcee88fe0abe
5import FlowToken from 0x1654653399040a61
6import EVM from 0xe467b9dd11fa00df
7
8/// DCATransactionHandlerEVMSimple: Minimal EVM handler (~100 lines)
9/// Tests if scheduler can execute EVM swaps at all
10/// NO autonomous rescheduling - just executes FLOW → USDF via COA
11access(all) contract DCATransactionHandlerEVMSimple {
12
13    access(all) struct SimpleData {
14        access(all) let planId: UInt64
15        init(planId: UInt64) { self.planId = planId }
16    }
17
18    access(all) event Started(transactionId: UInt64, planId: UInt64)
19    access(all) event Completed(transactionId: UInt64, planId: UInt64, amountIn: UFix64)
20    access(all) event Failed(transactionId: UInt64, planId: UInt64, reason: String)
21
22    access(all) resource Handler: FlowTransactionScheduler.TransactionHandler {
23        access(self) let controllerCap: Capability<auth(DCAControllerUnified.Owner) &DCAControllerUnified.Controller>
24
25        init(controllerCap: Capability<auth(DCAControllerUnified.Owner) &DCAControllerUnified.Controller>) {
26            pre { controllerCap.check(): "Invalid controller" }
27            self.controllerCap = controllerCap
28        }
29
30        access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) {
31            let txData = data as! SimpleData? ?? panic("SimpleData required")
32            emit Started(transactionId: id, planId: txData.planId)
33
34            let controller = self.controllerCap.borrow() ?? panic("No controller")
35            let plan = controller.borrowPlan(id: txData.planId) ?? panic("No plan")
36
37            // Get COA
38            let coaCap = controller.getCOACapability()
39            if coaCap == nil || !coaCap!.check() {
40                emit Failed(transactionId: id, planId: txData.planId, reason: "No COA")
41                return
42            }
43            let coa = coaCap!.borrow()!
44
45            // Get source vault and check balance
46            let sourceVaultCap = controller.getSourceVaultCapability()
47                ?? panic("No source vault")
48            let sourceVault = sourceVaultCap.borrow()
49                ?? panic("Cannot borrow source")
50
51            let amountIn = plan.amountPerInterval
52            if sourceVault.balance < amountIn {
53                emit Failed(transactionId: id, planId: txData.planId, reason: "Insufficient balance")
54                return
55            }
56
57            // Withdraw FLOW and deposit to COA
58            let flowToSwap <- sourceVault.withdraw(amount: amountIn) as! @FlowToken.Vault
59            coa.deposit(from: <-flowToSwap)
60
61            // Simple test: just deposit to COA and emit success
62            // In production, would call UniswapV3 router here
63
64            // Record execution
65            plan.recordExecution(amountIn: amountIn, amountOut: 0.0)
66
67            emit Completed(transactionId: id, planId: txData.planId, amountIn: amountIn)
68        }
69
70        access(all) view fun getViews(): [Type] {
71            return [Type<StoragePath>()]
72        }
73
74        access(all) fun resolveView(_ view: Type): AnyStruct? {
75            return /storage/DCATransactionHandlerEVMSimple
76        }
77    }
78
79    access(all) fun createHandler(
80        controllerCap: Capability<auth(DCAControllerUnified.Owner) &DCAControllerUnified.Controller>
81    ): @Handler {
82        return <- create Handler(controllerCap: controllerCap)
83    }
84
85    access(all) fun createData(planId: UInt64): SimpleData {
86        return SimpleData(planId: planId)
87    }
88}
89