【AI 實戰】當 DeFi 平台倒閉但你的幣還在裡面...

你是否也有幣被卡在已死的 DeFi 平台無法提領?別擔心!讓我分享如何成功從已死的 Autofarm 救出資產的實戰經驗 👊

【AI 實戰】當 DeFi 平台倒閉但你的幣還在裡面...
Photo by Markus Spiske / Unsplash

前情提要:意外發現的 40 美金

在某個百無聊賴的午後,我整理錢包時發現一個被遺忘的錢包裡居然躺著 40 美金!這是上輪牛市時在 Autofarm 挖礦留下的獎勵。(沒錯,就是那個已經掛掉、網站完全無法使用、Telegram 和 Discord 都已經停止運作的 Autofarm 😅)

這是從 Rabby 看到的紀錄,也要感謝 Rabby,不然根本不會發現

問題是,這筆錢還卡在 Autofarm 裡面

選擇題:放棄 VS 挑戰

40 美金,說多不多,說少...好吧其實真的不多 😂 但轉念一想:

  1. 這不就是學習跟智能合約互動的完美機會嗎?
  2. 我雖然什麼都不會,但我有 AI!
  3. 成功就賺 40 鎂!

很多時候我們都太依賴前端介面,好像沒有前端,錢就被卡住了。但智能合約和中心化交易所不一樣的地方就是「他就在那兒」,理論上是可以直接互動並提領出來的。

💡
重要觀念:智能合約的美妙之處在於 - 就算 DeFi 項目方已經潛逃,只要合約還在鏈上,你的資產就還在!

實戰開始!與 AI 攜手展開救援行動 🤖

Step 1:找到所有需要的資料

首先透過 Debank 確認資產,看起來卡在裡面的是 ALPACA。

但用 Zapper 交叉比對後,發現其實卡在裡面的不是 ALPACA,而是 ibALPACA

收集以下重要地址:

  • 我的錢包地址:0x62a07...d0e2
  • Autofarm 主合約:0x089...452
  • ibALPACA 合約:0xf1...d421

Step 2:尋找正確的資金池(史詩級挑戰)

Autofarm 主合約的提領動作需要設定 Pool ID,但我根本不知道我的錢是卡在哪個池子。

也無法直接查詢哪個池子是 ibALPACA。AI 建議我一個一個查,用 Read Contract 的 poolInfo 的確可以查。

可是,當我發現總共有 700+ 個資金池時... (開始流冷汗 💦)

使用 poolLength發現池子有 700 多個

感謝 AI 大神,幫我寫了一個使用 ethers.js 的腳本,一個一個資金池去查。 結果發現:

  • 488 號池:❌ 看起來對但餘額為 0
  • 487 號池:✅ Bingo!找到我們的目標!(他在暗示我是白痴嗎?)

腳本很簡單,只需用 node.js 和 ethers.js。

const { ethers } = require("ethers"); // 確保 ethers.js 已安裝

// Autofarm 主合約地址
const AUTO_FARM_CONTRACT = "0x0895196562C7868C5Be92459FaE7f877ED450452"; // 替換為 Autofarm 合約地址
const PROVIDER_URL = "https://bsc-dataseed.binance.org/"; // BSC 主網節點
const ALPACA_ADDRESS = "0xf1bE8ecC990cBcb90e166b71E368299f0116d421"; // ibALPACA 合約地址

const autofarmABI = [
    "function poolLength() external view returns (uint256)",
    "function poolInfo(uint256) external view returns (address, uint256, uint256, uint256, address)"
];

async function findALPACA() {
    // 正確初始化 JsonRpcProvider
    const provider = new ethers.JsonRpcProvider(PROVIDER_URL);
    const contract = new ethers.Contract(AUTO_FARM_CONTRACT, autofarmABI, provider);

    const poolLength = await contract.poolLength();
    console.log(`Total Pools: ${poolLength}`);

    // 遍歷所有池子,找到 ALPACA 的池子 ID
    for (let pid = 0; pid < poolLength; pid++) {
        const poolInfo = await contract.poolInfo(pid);
        const wantAddress = poolInfo[0]; // want 地址
        if (wantAddress.toLowerCase() === ALPACA_ADDRESS.toLowerCase()) {
            console.log(`Found ALPACA in Pool ID: ${pid}`);
            return pid;
        }
    }
    console.log("ALPACA not found in any pool.");
}

findALPACA().catch(console.error);

Step 3:提領資產(最驚險的時刻)

到 Write Contract 使用 withdrawwithdrawAll 都失敗了。

範例:https://bscscan.com/tx/0x03ed30bf32067d48677c68b90e46447f9a1950ab1ec2aa7e6acd5f661aae5069

確認 gas 沒有不夠後,用 emergencyWithdraw 功能... 3...2...1... 成功!🎉

Step 4:最後一哩路

將 ibALPACA 換回 ALPACA,進入 ibALPACA 合約,找看看有沒有 unwrap 功能。

  1. 先用 balanceOf 確認餘額
  2. 執行 withdraw,把餘額貼上

Etherscan 丟給我這個錯誤:

但是其實成功了,在錢包、Zapper 都看得到餘額。

任務完成,歡欣鼓舞!✨

同場加映:把所有合約程式碼一次貼給 AI

為了讓 AI 幫我們解釋 Read Contract 和 Write Contract 有哪些功能,我們可以把整個合約原始碼貼給 AI 看,以下是 Autofarm 主合約的 bscscan 合約頁面。右上角有複製按鈕。

但如果有多個檔案怎麼辦?像 Autofarm 單一池子的策略合約就有 15 個檔案,才懶得一個一個貼。這時,可以點原始碼區塊右上角的 Code Reader,進入一個 AI 專用的天地。

這邊的 AI 功能需要你提供 API Key。

但目前只有 GPT 3.5 和 4,因此不建議用這個介面,我們還是把完整原始碼複製,丟到我們自己的 AI 介面吧。要怎麼做呢?可以到左下角把檔案都點選起來,然後全選複製 Source Code 就好啦!

實戰心得

  1. 前端掛了不要慌,合約永遠在區塊鏈上
  2. AI 是 web3 實戰的好夥伴,建議善用
  3. 工具很重要:Debank、Etherscan、Zapper 都是必備良器

對這篇文章有什麼建議或想法嗎?請 按此在 Twitter 留言按此在 Threads 留言 ,我會回應你 :)