Skip to content

Commit 3346903

Browse files
Glory Matthewclaude
authored andcommitted
Add STX reserve flash loans with Bitflow arbitrage receiver
- New contracts: flashstack-stx-core, stx-test-receiver, bitflow-arb-receiver All deployed to mainnet at SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5 - stx-flash-receiver-trait deployed at SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ - 80 STX reserve seeded, both receivers whitelisted on-chain - Fix: use unwrap! for stx-transfer? to resolve Clarity 4 type mismatch - Deploy scripts: deploy-and-test-stx.mjs, continue-stx-setup.mjs - Frontend: receivers page shows STX + sBTC contracts with correct addresses - README: mainnet addresses, arbitrage strategy guide, economics table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5ad4331 commit 3346903

13 files changed

Lines changed: 1355 additions & 57 deletions

Clarinet.toml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ description = "FlashStack - Trustless flash minting of sBTC against locked/stack
44
authors = ["Glory Matthew"]
55
telemetry = false
66
cache_dir = "./.cache"
7-
requirements = []
7+
requirements = [
8+
{ contract_id = "SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.stx-flash-receiver-trait" },
9+
{ contract_id = "SPQC38PW542EQJ5M11CR25P7BS1CA6QT4TBXGB3M.stableswap-stx-ststx-v-1-2" },
10+
{ contract_id = "SPQC38PW542EQJ5M11CR25P7BS1CA6QT4TBXGB3M.stx-ststx-lp-token-v-1-2" },
11+
{ contract_id = "SP4SZE494VC2YC5JYG7AYFQ44F5Q4PYV7DVMDPBG.ststx-token" },
12+
]
813
boot_contracts = []
914

1015
[contracts.flashstack-core]
@@ -71,6 +76,24 @@ trusted_sender = false
7176
trusted_caller = false
7277
callee_filter = false
7378

79+
[contracts.flashstack-stx-core]
80+
path = "contracts/flashstack-stx-core.clar"
81+
clarity_version = 3
82+
epoch = 3.0
83+
depends_on = ["stx-flash-receiver-trait"]
84+
85+
[contracts.stx-test-receiver]
86+
path = "contracts/stx-test-receiver.clar"
87+
clarity_version = 3
88+
epoch = 3.0
89+
depends_on = ["stx-flash-receiver-trait", "flashstack-stx-core"]
90+
91+
[contracts.bitflow-arb-receiver]
92+
path = "contracts/bitflow-arb-receiver.clar"
93+
clarity_version = 3
94+
epoch = 3.0
95+
depends_on = ["stx-flash-receiver-trait", "flashstack-stx-core"]
96+
7497
[contracts.snp-flashstack-receiver]
7598
path = "contracts/snp-flashstack-receiver.clar"
7699
clarity_version = 2

README.md

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,33 @@
1414

1515
## Mainnet Deployment
1616

17-
All 13 contracts are live on Stacks mainnet:
17+
### STX Flash Loans (Reserve-Based) — New
18+
19+
| Contract | Address | Explorer |
20+
|---|---|---|
21+
| `flashstack-stx-core` | `SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5.flashstack-stx-core` | [View](https://explorer.hiro.so/txid/0x4c1a17483eb5bc42b4d7454ffc53f5b1fe4d18d1370b23b60199ee9d8d28ba70?chain=mainnet) |
22+
| `stx-flash-receiver-trait` | `SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.stx-flash-receiver-trait` | [View](https://explorer.hiro.so/txid/0x767d17c6d8ef98998cd48ce4ad47ed0432d29e74fb0e8fc12b0b353e975e57cf?chain=mainnet) |
23+
| `stx-test-receiver` | `SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5.stx-test-receiver` | [View](https://explorer.hiro.so/txid/0xfead69fa92f54e5790ff1b17a9479e86716e93b66357726d8c9be336df558e45?chain=mainnet) |
24+
| `bitflow-arb-receiver` | `SP20XD46NGAX05ZQZDKFYCCX49A3852BQABNP0VG5.bitflow-arb-receiver` | [View](https://explorer.hiro.so/txid/0x616449ab17cb75e3ddd4d2bbb2b7c38c0d4cd566b00035606d9a70bc08b637d4?chain=mainnet) |
25+
26+
Reserve: 80 STX seeded. Max single loan: 5,000 STX. Fee: 0.05%.
27+
28+
### sBTC Flash Loans (Mint/Burn) — Original
1829

1930
| Contract | Address |
2031
|---|---|
21-
| `flashstack-core` | [`SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.flashstack-core`](https://explorer.hiro.so/address/SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.flashstack-core) |
32+
| `flashstack-core` | [`SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.flashstack-core`](https://explorer.hiro.so/address/SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.flashstack-core?chain=mainnet) |
2233
| `sbtc-token` | `SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.sbtc-token` |
2334
| `flash-receiver-trait` | `SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.flash-receiver-trait` |
2435

2536
### Confirmed Mainnet Flash Loans
2637

27-
| # | Amount | Receiver | Strategy |
28-
|---|---|---|---|
29-
| 1 | 0.01 sBTC | `test-receiver` | Basic demonstration |
30-
| 2 | 0.05 sBTC | `test-receiver` | Basic demonstration |
31-
| 3 | 0.10 sBTC | `dex-aggregator-receiver` | DEX arbitrage |
38+
| # | Asset | Amount | Receiver | Tx |
39+
|---|---|---|---|---|
40+
| 1 | sBTC | 0.01 sBTC | `test-receiver` | Basic demonstration |
41+
| 2 | sBTC | 0.05 sBTC | `test-receiver` | Basic demonstration |
42+
| 3 | sBTC | 0.10 sBTC | `dex-aggregator-receiver` | DEX arbitrage |
43+
| 4 | STX | 80 STX reserve deposited | `flashstack-stx-core` | [View](https://explorer.hiro.so/txid/0x9dd66a9d5372cb843d1ecfdf47138e7e91cf7597f807dafdbb7e129e1da23040?chain=mainnet) |
3244

3345
### Previous Testnet Deployment
3446

@@ -105,6 +117,57 @@ All findings from an independent security review were addressed:
105117

106118
---
107119

120+
## Arbitrage Strategies
121+
122+
Flash loans are uncollateralized — you borrow zero capital and only pay the Stacks tx fee (~$0.002). The protocol guarantees: if your repayment fails, everything reverts. You never lose your own capital, only the gas fee.
123+
124+
### Strategy 1: stSTX Peg Arbitrage (Bitflow)
125+
126+
stSTX accumulates staking yield. When yield accrues, stSTX briefly trades above 1:1 STX on Bitflow before arbitrageurs equalize it. `bitflow-arb-receiver` captures this atomically:
127+
128+
```
129+
Borrow 1000 STX (free, uncollateralized)
130+
-> Swap 1000 STX -> 1012 stSTX on Bitflow (stSTX at 0.988 STX = above peg)
131+
-> Swap 1012 stSTX -> 1010 STX on Bitflow
132+
-> Repay 1000.05 STX (principal + 0.05% fee)
133+
-> Keep 9.95 STX profit, zero capital at risk
134+
```
135+
136+
**When to run:** Watch for stSTX/STX ratio on Bitflow rising above 1.0005 (0.05% spread covers the fee).
137+
138+
### Strategy 2: Cross-DEX Price Arbitrage
139+
140+
Same token, different price on two DEXes (e.g. ALEX vs Velar):
141+
142+
```
143+
Borrow 500 STX
144+
-> Buy TOKEN on ALEX at lower price
145+
-> Sell TOKEN on Velar at higher price
146+
-> Repay 500.025 STX + keep spread
147+
```
148+
149+
### Strategy 3: Liquidation Bot
150+
151+
A DeFi lending protocol lists undercollateralized positions. You borrow STX, repay the borrower's debt, receive discounted collateral, sell it, repay the flash loan, keep the liquidation bonus.
152+
153+
```
154+
Borrow 2000 STX
155+
-> Repay borrower's 2000 STX debt to lending protocol
156+
-> Receive 2200 STX worth of collateral (10% liquidation bonus)
157+
-> Sell collateral for 2200 STX
158+
-> Repay 2000.10 STX
159+
-> Keep 199.90 STX profit
160+
```
161+
162+
### Economics Summary
163+
164+
| Role | Capital required | Risk | Profit source |
165+
|---|---|---|---|
166+
| Borrower (you) | 0 STX | ~$0.002 tx fee if strategy fails | Arb spread minus 0.05% fee |
167+
| Reserve provider (admin) | 80+ STX locked | Reserve stays safe (reverts on failure) | 0.05% fee on every loan |
168+
169+
---
170+
108171
## Integration Guide
109172

110173
### Build a Flash Loan Receiver
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
;; Bitflow Arbitrage Receiver
2+
;; Borrows STX from flashstack-stx-core, executes STX/stSTX round-trip
3+
;; on Bitflow stableswap, repays with profit.
4+
;;
5+
;; Live contracts used:
6+
;; Bitflow pool: SPQC38PW542EQJ5M11CR25P7BS1CA6QT4TBXGB3M.stableswap-stx-ststx-v-1-2
7+
;; stSTX token: SP4SZE494VC2YC5JYG7AYFQ44F5Q4PYV7DVMDPBG.ststx-token
8+
;;
9+
;; Why this works:
10+
;; stSTX accumulates staking yield. When yield accrues, stSTX briefly
11+
;; trades above 1 STX on Bitflow before arbitrageurs equalise it.
12+
;; This receiver captures that spread atomically in one flash loan tx.
13+
;;
14+
;; Bitflow swap-x-for-y: STX (x) -> stSTX (y)
15+
;; Bitflow swap-y-for-x: stSTX (y) -> STX (x)
16+
17+
(impl-trait 'SP3TGRVG7DKGFVRTTVGGS60S59R916FWB4DAB9STZ.stx-flash-receiver-trait.stx-flash-receiver-trait)
18+
19+
;; Minimal SIP-010 trait for calling stSTX token
20+
(define-trait sip-010-trait
21+
(
22+
(transfer (uint principal principal (optional (buff 34))) (response bool uint))
23+
(get-name () (response (string-ascii 32) uint))
24+
(get-symbol () (response (string-ascii 32) uint))
25+
(get-decimals () (response uint uint))
26+
(get-balance (principal) (response uint uint))
27+
(get-total-supply () (response uint uint))
28+
(get-token-uri () (response (optional (string-utf8 256)) uint))
29+
)
30+
)
31+
32+
;; =============================================
33+
;; Constants
34+
;; =============================================
35+
36+
(define-constant CONTRACT-OWNER tx-sender)
37+
38+
(define-constant ERR-NOT-OWNER (err u400))
39+
(define-constant ERR-SWAP-FAILED (err u401))
40+
(define-constant ERR-NO-PROFIT (err u402))
41+
(define-constant ERR-REPAY-FAILED (err u403))
42+
43+
;; Bitflow STX/stSTX stableswap pool
44+
(define-constant BITFLOW-POOL 'SPQC38PW542EQJ5M11CR25P7BS1CA6QT4TBXGB3M.stableswap-stx-ststx-v-1-2)
45+
46+
;; stSTX SIP-010 token (y-token in the pool)
47+
(define-constant STSTX 'SP4SZE494VC2YC5JYG7AYFQ44F5Q4PYV7DVMDPBG.ststx-token)
48+
49+
;; Bitflow STX/stSTX LP token (lp-token parameter)
50+
(define-constant BITFLOW-LP 'SPQC38PW542EQJ5M11CR25P7BS1CA6QT4TBXGB3M.stx-ststx-lp-token-v-1-2)
51+
52+
;; Slippage tolerance in basis points (default 100 = 1%)
53+
(define-data-var slippage-bp uint u100)
54+
55+
;; =============================================
56+
;; Flash Loan Callback
57+
;; =============================================
58+
59+
(define-public (execute-stx-flash (amount uint) (core principal))
60+
(let (
61+
;; Calculate repayment
62+
(fee-bp (unwrap! (contract-call? .flashstack-stx-core get-fee-basis-points) ERR-SWAP-FAILED))
63+
(raw-fee (/ (* amount fee-bp) u10000))
64+
(fee (if (> raw-fee u0) raw-fee u1))
65+
(total-owed (+ amount fee))
66+
67+
;; Min stSTX out from leg 1 (amount minus slippage)
68+
(slip (var-get slippage-bp))
69+
(min-ststx (- amount (/ (* amount slip) u10000)))
70+
71+
;; Min STX back from leg 2 (must cover total-owed)
72+
(min-stx total-owed)
73+
)
74+
;; Leg 1: STX -> stSTX on Bitflow
75+
(unwrap! (contract-call? BITFLOW-POOL swap-x-for-y
76+
STSTX ;; y-token (stSTX SIP-010)
77+
BITFLOW-LP ;; lp-token (LP token for this pool)
78+
amount ;; STX amount in microstacks
79+
min-ststx ;; minimum stSTX to receive
80+
) ERR-SWAP-FAILED)
81+
82+
;; Get how much stSTX we received
83+
(let (
84+
(ststx-balance (unwrap!
85+
(contract-call? STSTX get-balance (as-contract tx-sender))
86+
ERR-SWAP-FAILED))
87+
)
88+
(asserts! (> ststx-balance u0) ERR-SWAP-FAILED)
89+
90+
;; Leg 2: stSTX -> STX on Bitflow
91+
(unwrap! (contract-call? BITFLOW-POOL swap-y-for-x
92+
STSTX ;; y-token (stSTX SIP-010)
93+
BITFLOW-LP ;; lp-token (LP token for this pool)
94+
ststx-balance ;; all stSTX we hold
95+
min-stx ;; minimum STX back (must cover repayment)
96+
) ERR-SWAP-FAILED)
97+
98+
;; Repay STX + fee back to flashstack-stx-core
99+
(let ((stx-now (stx-get-balance (as-contract tx-sender))))
100+
(asserts! (>= stx-now total-owed) ERR-REPAY-FAILED)
101+
(unwrap! (as-contract (stx-transfer? total-owed tx-sender core)) ERR-REPAY-FAILED)
102+
(ok true)
103+
)
104+
)
105+
)
106+
)
107+
108+
;; =============================================
109+
;; Admin
110+
;; =============================================
111+
112+
(define-public (set-slippage-bp (new-bp uint))
113+
(begin
114+
(asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-OWNER)
115+
(asserts! (<= new-bp u500) ERR-SWAP-FAILED) ;; max 5% slippage
116+
(ok (var-set slippage-bp new-bp))
117+
)
118+
)
119+
120+
;; Rescue stuck STX (admin only)
121+
(define-public (rescue-stx (amount uint) (to principal))
122+
(begin
123+
(asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-OWNER)
124+
(unwrap! (as-contract (stx-transfer? amount tx-sender to)) ERR-NOT-OWNER)
125+
(ok true)
126+
)
127+
)
128+
129+
;; =============================================
130+
;; Read-only
131+
;; =============================================
132+
133+
(define-read-only (get-slippage-bp)
134+
(ok (var-get slippage-bp))
135+
)
136+
137+
(define-read-only (estimate-profit (amount uint))
138+
(let (
139+
(fee-bp (unwrap-panic (contract-call? .flashstack-stx-core get-fee-basis-points)))
140+
(raw-fee (/ (* amount fee-bp) u10000))
141+
(fee (if (> raw-fee u0) raw-fee u1))
142+
(slip (var-get slippage-bp))
143+
(min-ststx (- amount (/ (* amount slip) u10000)))
144+
)
145+
(ok {
146+
loan-amount: amount,
147+
fee-to-pay: fee,
148+
total-owed: (+ amount fee),
149+
min-ststx-leg1: min-ststx,
150+
note: "Profit = STX received from leg2 - total-owed. Positive when stSTX trades above peg."
151+
})
152+
)
153+
)

0 commit comments

Comments
 (0)