Type/to search
8
Follow
1364
Followers
Amalan Ethereum Web3 Platform FMZ - Pertukaran Pesanan Berdasarkan Kontrak Pintar
Discussions
Created 2025-03-17 11:00:33  Updated 2025-03-18 15:54:46
 0
 883

img

Mukadimah

Dalam pasaran mata wang kripto, peluang perdagangan adalah sekejap, terutamanya tingkap arbitraj hasil tinggi, yang selalunya hanya bertahan untuk masa yang sangat singkat. Jika anda hanya bergantung pada dagangan manual, selalunya sukar untuk bersaing dengan pasaran. Oleh itu, dagangan pesanan belum selesai menjadi cara penting untuk meningkatkan kecekapan dagangan.

Artikel ini berdasarkan idea artikel Xiaocao Ia membina semula strategi pesanan kumpulan dagangan Curve.fi pada platform FMZ dan memperkenalkan cara untuk mencapai kesan yang sama melalui platform FMZ. Pada masa yang sama, skim perlindungan kunci persendirian juga akan dibincangkan secara terperinci untuk memastikan keselamatan dan kemudahan dalam proses perdagangan terprogram.

Strategi ini ditulis dalam JavaScript dan menggunakan objek pertukaran web3 eth platform FMZ.

Keselamatan mengikut reka bentuk

Berdasarkan artikel tersebut「Bagaimana untuk melaksanakan penempatan pesanan dalam pertukaran terdesentralisasi - mengambil Curve sebagai contoh」Dalam reka bentuk keselamatan, kami menggunakan kaedah penyulitan AES yang serupa. Kami menggunakan kata laluan dan kiraan untuk menyulitkan data.

  • Kata laluan: kata laluan , dicincang dengan sha256.
  • Kira: kira, gunakan cap masa sebagai kiraan rawak untuk mengambil bahagian dalam penyulitan.
  1. Sulitkan kunci persendirian di luar talian, gunakan "kata laluan" dan "kira" untuk menyulitkan kunci persendirian dan dapatkan kunci rahsia yang disulitkan.
  2. Konfigurasikan kunci yang disulitkan, kata laluan, kiraan, dsb. ke platform FMZ, dan gunakan kawalan parameter antara muka dasar "String Disulitkan" Kandungan yang dimasukkan dalam kawalan akan disulitkan, dan maklumat konfigurasi yang direkodkan pada platform bukanlah kandungan teks biasa dalam kawalan.
  3. Apabila strategi berjalan, penjaga boleh menyahsulit maklumat dan memuatkan kunci rahsia (selepas memuatkan kunci rahsia, semua pembolehubah yang berkaitan akan ditetapkan semula).

img

javascript
// 加密/解密方式 function cryptoKey(type, data, passWord, count) { // 加载加密库 eval(HttpQuery("https://cdnjs.cloudflare.com/ajax/libs/aes-js/3.1.2/index.min.js")) // sha256 密码 var hash = Encode("sha256", "string", "hex", passWord).substring(0, 32) if (type == "encrypt") { var key = aesjs.utils.utf8.toBytes(hash.substring(0, 32)) var counter = new aesjs.Counter(count) var textBytes = aesjs.utils.utf8.toBytes(data) var aesCtr = new aesjs.ModeOfOperation.ctr(key, counter) var encryptedBytes = aesCtr.encrypt(textBytes) var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes) return encryptedHex } else if (type == "decrypt") { var key = aesjs.utils.utf8.toBytes(hash.substring(0, 32)) var counter = new aesjs.Counter(count) var aesCtrDecrypt = new aesjs.ModeOfOperation.ctr(key, counter) const decryptedBytes = aesCtrDecrypt.decrypt(aesjs.utils.hex.toBytes(data)) const decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes) return decryptedText } else { throw "function cryptoKey(), param 'type' not support" } }

Konfigurasikan objek pertukaran web3

https://www.fmz.com/m/platforms/add

img

Terdapat banyak nod Ethereum yang tersedia dalam talian, yang biasa digunakan ialah:

Anda boleh memohon untuk membuat alamat anda sendiri dan kemudian mengkonfigurasinya untuk digunakan. Saya tidak akan menerangkan butiran di sini. Anda boleh mengisi maklumat penting sesuka hati Kami merancang untuk memuatkannya secara dinamik, jadi tiada gunanya mengkonfigurasinya di sini.

javascript
exchange.IO("key", cryptoKey(descCryptoType[cryptoType], keyData, password, count)) walletAddress = exchange.IO("address") Log("载入秘钥,钱包地址:", walletAddress)

Gunakan fungsi exchange.IO("kunci", ...) yang dirangkumkan oleh platform untuk memuatkan dan mengemas kini kunci peribadi selepas penyahsulitan.

Daftar ABI

Selepas menyelesaikan isu keselamatan, langkah seterusnya ialah melakukan beberapa operasi pada kontrak pintar Ethereum. Menurut Curve.fi DEX yang disebut oleh Xiaocao, kita boleh mencari dApp ini dalam talian dengan mudah:

https://curve.fi/dex/ethereum/pools/factory-stable-ng-102/deposit/

Pada halaman kumpulan pertukaran sDAI/sUSDe, anda boleh mencari alamat kontrak kumpulan pertukaran dan mematuhi kontrak. Kaedah yang boleh kami gunakan ialah:

  • syiling: Dapatkan alamat kontrak token yang mengambil bahagian dalam transaksi dalam kumpulan
  • get_dy: Kira kuantiti pertukaran semasa dalam kumpulan.
  • pertukaran: melaksanakan pertukaran.

Untuk memanggil kaedah ini, anda perlu mendaftarkan ABI kontrak kumpulan terlebih dahulu. Saya tidak menapis kaedah yang digunakan, tetapi terus menyalin dan menampal ABI yang lengkap dan kemudian mendaftarkannya.

javascript
// sDAI/sUSDe 池合约地址和ABI var poolAddress = "0x167478921b907422F8E88B43C4Af2B8BEa278d3A" // 合约ABI var poolABI = `[{"name":"Transfer","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true},{"name":"spender","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchange","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchangeUnderlying","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[]","indexed":false},{"name":"fees","type":"uint256[]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[]","indexed":false},{"name":"fees","type":"uint256[]","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityOne","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_id","type":"int128","indexed":false},{"name":"token_amount","type":"uint256","indexed":false},{"name":"coin_amount","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityImbalance","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[]","indexed":false},{"name":"fees","type":"uint256[]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RampA","inputs":[{"name":"old_A","type":"uint256","indexed":false},{"name":"new_A","type":"uint256","indexed":false},{"name":"initial_time","type":"uint256","indexed":false},{"name":"future_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"StopRampA","inputs":[{"name":"A","type":"uint256","indexed":false},{"name":"t","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"ApplyNewFee","inputs":[{"name":"fee","type":"uint256","indexed":false},{"name":"offpeg_fee_multiplier","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetNewMATime","inputs":[{"name":"ma_exp_time","type":"uint256","indexed":false},{"name":"D_ma_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_A","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_offpeg_fee_multiplier","type":"uint256"},{"name":"_ma_exp_time","type":"uint256"},{"name":"_coins","type":"address[]"},{"name":"_rate_multipliers","type":"uint256[]"},{"name":"_asset_types","type":"uint8[]"},{"name":"_method_ids","type":"bytes4[]"},{"name":"_oracles","type":"address[]"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"exchange_received","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"exchange_received","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_min_mint_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_min_mint_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_max_burn_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_max_burn_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[]"}],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[]"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[]"},{"name":"_receiver","type":"address"},{"name":"_claim_admin_fees","type":"bool"}],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw_admin_fees","inputs":[],"outputs":[]},{"stateMutability":"view","type":"function","name":"last_price","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"ema_price","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_p","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"price_oracle","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"D_oracle","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"permit","inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_deadline","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"view","type":"function","name":"get_dx","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_dy","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"calc_withdraw_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_virtual_price","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"calc_token_amount","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_is_deposit","type":"bool"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"A","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"A_precise","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balances","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_balances","inputs":[],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"view","type":"function","name":"stored_rates","inputs":[],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"view","type":"function","name":"dynamic_fee","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"ramp_A","inputs":[{"name":"_future_A","type":"uint256"},{"name":"_future_time","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"stop_ramp_A","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_new_fee","inputs":[{"name":"_new_fee","type":"uint256"},{"name":"_new_offpeg_fee_multiplier","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_ma_exp_time","inputs":[{"name":"_ma_exp_time","type":"uint256"},{"name":"_D_ma_time","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"N_COINS","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"offpeg_fee_multiplier","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"initial_A","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"future_A","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"initial_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"future_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"admin_balances","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"ma_exp_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"D_ma_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"ma_last_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8"}]},{"stateMutability":"view","type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"nonces","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"salt","inputs":[],"outputs":[{"name":"","type":"bytes32"}]}]` // 注册ABI exchange.IO("abi", poolAddress, poolABI)

Baca baki dompet dan baki token

Membaca baki token dompet, ketepatan token, nama token, dll. adalah semua kaedah kontrak ERC20, yang didaftarkan secara lalai.

javascript
var token0Name = exchange.IO("api", token0Address, "symbol") var token1Name = exchange.IO("api", token1Address, "symbol") var token0Decimals = exchange.IO("api", token0Address, "decimals") var token1Decimals = exchange.IO("api", token1Address, "decimals")
javascript
var sDAI_Balance = exchange.IO("api", sDAI["address"], "balanceOf", walletAddress) var sUSDe_Balance = exchange.IO("api", sUSDe["address"], "balanceOf", walletAddress)

Memantau kolam pertukaran

javascript
function getBuyProfit(poolAddress, sDAI, sUSDe, amountIn, entryPriceForDAI) { var data = exchange.IO("api", poolAddress, "get_dy", sDAI["idx"], sUSDe["idx"], toInnerAmount(amountIn, sDAI["decimals"])) Log("get_dy:", data) var amountOut = toAmount(data, sUSDe["decimals"]) if (!amountOut) { return null } var profit = amountOut - entryPriceForDAI * amountIn return {"profit": profit, "amountOut": amountOut, "sDAI_sUSDe_price": amountOut / amountIn} }

Keadaan pencetus direka seperti berikut:

javascript
if (profit > 1000 && sDAI_Balance > amountIn) { Log("达到兑换条件,开始执行 sDAI -> sUSDe 兑换交易...") /* 兑换操作代码仅为教学演示,该功能请慎用,请先测试 executeTrade(poolAddress, sDAI, sUSDe, amountIn, 0.999*amountOut) */ }

Operasi pertukaran hanya boleh dilakukan apabila jumlah pertukaran semasa memenuhi keuntungan lebih daripada 1000 dan terdapat cukup token sDAI dalam dompet.

Operasi Pertukaran

javascript
function executeTrade(poolAddress, tokenIn, tokenOut, amountIn, minOutAmount) { // exchange : i , j , _dx , _min_dy var swapTx = exchange.IO("api", poolAddress, "exchange", tokenIn["idx"], tokenOut["idx"], toInnerAmount(amountIn, tokenIn["decimals"]), toInnerAmount(minOutAmount, tokenOut["decimals"])) if (swapTx) { while (true) { Sleep(1000 * 3) let info = e.IO("api", "eth", "eth_getTransactionReceipt", swapTx) if (info && info.gasUsed) { return true } Log('Transaction not yet mined', swapTx) } } return false }

img

Kod strategi penuh

javascript
function toAmount(s, decimals) { return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString()) } function toInnerAmount(n, decimals) { return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0) } function getBuyProfit(poolAddress, sDAI, sUSDe, amountIn, entryPriceForDAI) { var data = exchange.IO("api", poolAddress, "get_dy", sDAI["idx"], sUSDe["idx"], toInnerAmount(amountIn, sDAI["decimals"])) var amountOut = toAmount(data, sUSDe["decimals"]) if (!amountOut) { return null } var profit = amountOut - entryPriceForDAI * amountIn return {"profit": profit, "amountOut": amountOut, "sDAI_sUSDe_price": amountOut / amountIn} } function executeTrade(poolAddress, tokenIn, tokenOut, amountIn, minOutAmount) { // exchange : i , j , _dx , _min_dy var swapTx = exchange.IO("api", poolAddress, "exchange", tokenIn["idx"], tokenOut["idx"], toInnerAmount(amountIn, tokenIn["decimals"]), toInnerAmount(minOutAmount, tokenOut["decimals"])) if (swapTx) { while (true) { Sleep(1000 * 3) let info = e.IO("api", "eth", "eth_getTransactionReceipt", swapTx) if (info && info.gasUsed) { return true } Log('Transaction not yet mined', swapTx) } } return false } // 加密/解密方式 function cryptoKey(type, data, passWord, count) { // 加载加密库 eval(HttpQuery("https://cdnjs.cloudflare.com/ajax/libs/aes-js/3.1.2/index.min.js")) // sha256 密码 var hash = Encode("sha256", "string", "hex", passWord).substring(0, 32) if (type == "encrypt") { var key = aesjs.utils.utf8.toBytes(hash.substring(0, 32)) var counter = new aesjs.Counter(count) var textBytes = aesjs.utils.utf8.toBytes(data) var aesCtr = new aesjs.ModeOfOperation.ctr(key, counter) var encryptedBytes = aesCtr.encrypt(textBytes) var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes) return encryptedHex } else if (type == "decrypt") { var key = aesjs.utils.utf8.toBytes(hash.substring(0, 32)) var counter = new aesjs.Counter(count) var aesCtrDecrypt = new aesjs.ModeOfOperation.ctr(key, counter) const decryptedBytes = aesCtrDecrypt.decrypt(aesjs.utils.hex.toBytes(data)) const decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes) return decryptedText } else { throw "function cryptoKey(), param 'type' not support" } } // 加密/解密选项 const descCryptoType = ["encrypt", "decrypt"] function main() { LogReset(1) var count = _G("count") if (!count) { count = new Date().getTime() _G("count", count) } var walletAddress = null if (cryptoType == 1) { exchange.IO("key", cryptoKey(descCryptoType[cryptoType], keyData, password, count)) walletAddress = exchange.IO("address") Log("载入秘钥,钱包地址:", walletAddress) } else { Log("加密后的秘钥:", cryptoKey(descCryptoType[cryptoType], keyData, password, count)) return } Log("钱包ETH余额:", toAmount(exchange.IO("api", "eth", "eth_getBalance", walletAddress, "latest"), 18)) // sDAI/sUSDe 池合约地址和ABI var poolAddress = "0x167478921b907422F8E88B43C4Af2B8BEa278d3A" // 合约ABI var poolABI = `[{"name":"Transfer","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true},{"name":"spender","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchange","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchangeUnderlying","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[]","indexed":false},{"name":"fees","type":"uint256[]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[]","indexed":false},{"name":"fees","type":"uint256[]","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityOne","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_id","type":"int128","indexed":false},{"name":"token_amount","type":"uint256","indexed":false},{"name":"coin_amount","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityImbalance","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[]","indexed":false},{"name":"fees","type":"uint256[]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RampA","inputs":[{"name":"old_A","type":"uint256","indexed":false},{"name":"new_A","type":"uint256","indexed":false},{"name":"initial_time","type":"uint256","indexed":false},{"name":"future_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"StopRampA","inputs":[{"name":"A","type":"uint256","indexed":false},{"name":"t","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"ApplyNewFee","inputs":[{"name":"fee","type":"uint256","indexed":false},{"name":"offpeg_fee_multiplier","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetNewMATime","inputs":[{"name":"ma_exp_time","type":"uint256","indexed":false},{"name":"D_ma_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_A","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_offpeg_fee_multiplier","type":"uint256"},{"name":"_ma_exp_time","type":"uint256"},{"name":"_coins","type":"address[]"},{"name":"_rate_multipliers","type":"uint256[]"},{"name":"_asset_types","type":"uint8[]"},{"name":"_method_ids","type":"bytes4[]"},{"name":"_oracles","type":"address[]"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"exchange_received","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"exchange_received","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_min_mint_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_min_mint_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_max_burn_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_max_burn_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[]"}],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[]"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[]"},{"name":"_receiver","type":"address"},{"name":"_claim_admin_fees","type":"bool"}],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw_admin_fees","inputs":[],"outputs":[]},{"stateMutability":"view","type":"function","name":"last_price","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"ema_price","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_p","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"price_oracle","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"D_oracle","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"permit","inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_deadline","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"view","type":"function","name":"get_dx","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_dy","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"calc_withdraw_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_virtual_price","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"calc_token_amount","inputs":[{"name":"_amounts","type":"uint256[]"},{"name":"_is_deposit","type":"bool"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"A","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"A_precise","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balances","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_balances","inputs":[],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"view","type":"function","name":"stored_rates","inputs":[],"outputs":[{"name":"","type":"uint256[]"}]},{"stateMutability":"view","type":"function","name":"dynamic_fee","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"ramp_A","inputs":[{"name":"_future_A","type":"uint256"},{"name":"_future_time","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"stop_ramp_A","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_new_fee","inputs":[{"name":"_new_fee","type":"uint256"},{"name":"_new_offpeg_fee_multiplier","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_ma_exp_time","inputs":[{"name":"_ma_exp_time","type":"uint256"},{"name":"_D_ma_time","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"N_COINS","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"offpeg_fee_multiplier","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"initial_A","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"future_A","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"initial_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"future_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"admin_balances","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"ma_exp_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"D_ma_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"ma_last_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8"}]},{"stateMutability":"view","type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"nonces","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"salt","inputs":[],"outputs":[{"name":"","type":"bytes32"}]}]` // 注册ABI exchange.IO("abi", poolAddress, poolABI) // 获取池子中的代币地址、名称 var token0Address = exchange.IO("api", poolAddress, "coins", 0) var token1Address = exchange.IO("api", poolAddress, "coins", 1) var token0Name = exchange.IO("api", token0Address, "symbol") var token1Name = exchange.IO("api", token1Address, "symbol") var token0Decimals = exchange.IO("api", token0Address, "decimals") var token1Decimals = exchange.IO("api", token1Address, "decimals") var sDAI = {} var sUSDe = {} if (token0Name == "sDAI") { sDAI["name"] = token0Name sDAI["address"] = token0Address sDAI["idx"] = 0 sDAI["decimals"] = token0Decimals ? token0Decimals : 18 } else { throw "pool error" } if (token1Name == "sUSDe") { sUSDe["name"] = token1Name sUSDe["address"] = token1Address sUSDe["idx"] = 1 sUSDe["decimals"] = token1Decimals ? token1Decimals : 18 } else { throw "pool error" } // 假设 DAI 入手成本价: 0.9929 var entryPriceForDAI = 0.9929 while (true) { var sDAI_Balance = exchange.IO("api", sDAI["address"], "balanceOf", walletAddress) var sUSDe_Balance = exchange.IO("api", sUSDe["address"], "balanceOf", walletAddress) if (!sDAI_Balance || !sUSDe_Balance) { Sleep(1000 * 5) continue } var tbl = {"type": "table", "title": "data", "cols": ["tokenName", "address", "idx", "decimals", "balance"], "rows": []} tbl["rows"].push([sDAI["name"], sDAI["address"], sDAI["idx"], sDAI["decimals"], toAmount(sDAI_Balance, sDAI["decimals"])]) tbl["rows"].push([sUSDe["name"], sUSDe["address"], sUSDe["idx"], sUSDe["decimals"], toAmount(sUSDe_Balance, sUSDe["decimals"])]) // 监控兑换价格,根据 DAI 入手成本价,计算实时利润等信息 var amountIn = 100000 var ret = getBuyProfit(poolAddress, sDAI, sUSDe, amountIn, entryPriceForDAI) if (!ret) { Sleep(1000 * 5) continue } var profit = ret["profit"] var amountOut = ret["amountOut"] var sDAI_sUSDe_price = ret["sDAI_sUSDe_price"] if (profit > 1000 && sDAI_Balance > amountIn) { Log("达到兑换条件,开始执行 sDAI -> sUSDe 兑换交易...") /* 兑换操作代码仅为教学演示,该功能请慎用,请先测试 executeTrade(poolAddress, sDAI, sUSDe, amountIn, 0.999*amountOut) */ } LogStatus(_D(), ", amountIn:", amountIn, ", amountOut:", amountOut, ", sDAI_sUSDe_price:", sDAI_sUSDe_price, ", profit:", profit, "\n`" + JSON.stringify(tbl) + "`") Sleep(1000 * 60) } }

END

Menurut idea reka bentuk strategi asal, matlamatnya adalah untuk menangkap keadaan pasaran yang melampau sama seperti yang ditunjukkan dalam rajah.

img

Terima kasih atas bacaan dan sokongan anda.

Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)