Smart Contract
IncrementStakingStrategy
A.79f5b5b0f95a160b.IncrementStakingStrategy
1import FungibleToken from 0xf233dcee88fe0abe
2import FlowToken from 0x1654653399040a61
3import stFlowToken from 0xd6f80565193ad727
4import LiquidStaking from 0xd6f80565193ad727
5
6/// Increment Fi liquid staking strategy
7/// Stakes FLOW to receive stFLOW
8access(all) contract IncrementStakingStrategy {
9
10 access(all) event Staked(flowAmount: UFix64, stFlowReceived: UFix64)
11 access(all) event Unstaked(stFlowAmount: UFix64, flowReceived: UFix64)
12 access(all) event StrategyExecuted(amount: UFix64, result: UFix64)
13
14 access(self) var totalFlowStaked: UFix64
15 access(self) var totalStFlowReceived: UFix64
16
17 access(all) resource Strategy {
18 access(self) let flowVault: @FlowToken.Vault
19 access(self) let stFlowVault: @stFlowToken.Vault
20
21 init() {
22 self.flowVault <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) as! @FlowToken.Vault
23 self.stFlowVault <- stFlowToken.createEmptyVault(vaultType: Type<@stFlowToken.Vault>()) as! @stFlowToken.Vault
24 }
25
26 /// Execute staking: FLOW -> stFLOW
27 access(all) fun executeStrategy(from: @FlowToken.Vault): @stFlowToken.Vault {
28 pre {
29 from.balance > 0.0: "Cannot stake zero FLOW"
30 }
31
32 let flowAmount = from.balance
33
34 // Stake FLOW via LiquidStaking
35 let stFlowVault <- LiquidStaking.stake(flowVault: <-from)
36 let stFlowReceived = stFlowVault.balance
37
38 IncrementStakingStrategy.totalFlowStaked = IncrementStakingStrategy.totalFlowStaked + flowAmount
39 IncrementStakingStrategy.totalStFlowReceived = IncrementStakingStrategy.totalStFlowReceived + stFlowReceived
40
41 emit Staked(flowAmount: flowAmount, stFlowReceived: stFlowReceived)
42 emit StrategyExecuted(amount: flowAmount, result: stFlowReceived)
43
44 return <- stFlowVault
45 }
46
47 /// Harvest any accrued stFLOW
48 access(all) fun harvest(): @stFlowToken.Vault {
49 let balance = self.stFlowVault.balance
50
51 if balance > 0.0 {
52 return <- self.stFlowVault.withdraw(amount: balance) as! @stFlowToken.Vault
53 } else {
54 return <- stFlowToken.createEmptyVault(vaultType: Type<@stFlowToken.Vault>()) as! @stFlowToken.Vault
55 }
56 }
57
58 /// Emergency exit - return all stFLOW
59 access(all) fun emergencyExit(): @stFlowToken.Vault {
60 let balance = self.stFlowVault.balance
61
62 if balance > 0.0 {
63 return <- self.stFlowVault.withdraw(amount: balance) as! @stFlowToken.Vault
64 } else {
65 return <- stFlowToken.createEmptyVault(vaultType: Type<@stFlowToken.Vault>()) as! @stFlowToken.Vault
66 }
67 }
68
69 /// Get current balances
70 access(all) fun getBalances(): {String: UFix64} {
71 return {
72 "flow": self.flowVault.balance,
73 "stflow": self.stFlowVault.balance
74 }
75 }
76 }
77
78 access(all) fun createStrategy(): @Strategy {
79 return <- create Strategy()
80 }
81
82 access(all) fun getMetrics(): {String: UFix64} {
83 return {
84 "totalFlowStaked": self.totalFlowStaked,
85 "totalStFlowReceived": self.totalStFlowReceived,
86 "exchangeRate": self.totalFlowStaked > 0.0 ? self.totalStFlowReceived / self.totalFlowStaked : 1.0
87 }
88 }
89
90 init() {
91 self.totalFlowStaked = 0.0
92 self.totalStFlowReceived = 0.0
93 }
94}