Files
wtf-contract/scripts/real_trade_test.js
T

98 lines
4.4 KiB
JavaScript

// 真实链上交易验证:授权 -> 买入 OT -> 卖出 OT
// 用法: npx hardhat run scripts/real_trade_test.js --network robinhoodTestnet
const hre = require("hardhat");
const { ethers } = hre;
const MARKET = "0x048E9a90C25ba2c4410425D282b19A472e076039";
const CURVE = "0xF0E189974c413506098AFB6Bc6Bf4C6715fBf7B1";
const COLLATERAL = "0xe776e957953EA69b7Eaa9d7d4098aBC076bDD5E7";
const marketAbi = [
"function mintCollateralToExactOt(address receiver, uint256 tokenId, uint256 otDeltaOut, bytes dataSwap) returns (uint256 collateralIn)",
"function redeemExactOtToCollateral(address receiver, uint256 tokenId, uint256 otDeltaIn, bytes dataSwap) returns (uint256 collateralOut)",
"function balanceOf(address owner, uint256 id) view returns (uint256)",
"function readMarketState() view returns (tuple(address market, address curve, uint128 timestampStart, uint256 totalMarketCap, address treasury, uint256 numOutcomes, uint128 timestampEnd, uint256 answer, bool isFinalised))",
];
const curveAbi = [
"function calMarginalPrice(address market, uint256 tokenId) view returns (uint256)",
"function calMintCostByOtDelta(address market, uint256 tokenId, uint256 otDelta, bytes data) view returns (uint256 collateralFromUser, uint256 collateralToTreasury)",
"function calRedeemValueByOtDelta(address market, uint256 tokenId, uint256 otDelta, bytes data) view returns (uint256 collateralToUser, uint256 collateralToTreasury)",
];
const erc20Abi = [
"function balanceOf(address) view returns (uint256)",
"function allowance(address owner, address spender) view returns (uint256)",
"function approve(address spender, uint256 amount) returns (bool)",
"function mint(address to, uint256 amount) external",
];
const OT = 1000n * 10n ** 18n; // 买 1000 OT
const OUTCOME = 1; // tokenId = 1 << 0 = 1 (YES)
async function main() {
const provider = hre.ethers.provider;
const [signer] = await hre.ethers.getSigners();
console.log("Signer:", signer.address);
console.log("Block:", await provider.getBlockNumber());
const market = new hre.ethers.Contract(MARKET, marketAbi, signer);
const curve = new hre.ethers.Contract(CURVE, curveAbi, provider);
const wusd = new hre.ethers.Contract(COLLATERAL, erc20Abi, signer);
// 1) 水龙头: 余额不足则 mint 100_000 WUSD
const bal = await wusd.balanceOf(signer.address);
console.log("WUSD balance:", ethers.formatEther(bal));
if (bal < ethers.parseEther("10000")) {
console.log("> minting 100000 WUSD...");
const tx = await wusd.mint(signer.address, ethers.parseEther("100000"));
await tx.wait();
console.log(" minted, tx:", tx.hash);
}
// 2) 授权
const allowance = await wusd.allowance(signer.address, MARKET);
console.log("allowance -> market:", ethers.formatEther(allowance));
if (allowance < ethers.parseEther("100000")) {
console.log("> approve MaxUint256 to market...");
const tx = await wusd.approve(MARKET, ethers.MaxUint256);
await tx.wait();
console.log(" approved, tx:", tx.hash);
}
// 3) 价格与成本
const price = await curve.calMarginalPrice(MARKET, OUTCOME);
console.log("marginalPrice:", ethers.formatEther(price), "WUSD/OT");
const [cost, treasury] = await curve.calMintCostByOtDelta(MARKET, OUTCOME, OT, "0x");
console.log("cost for 1000 OT:", ethers.formatEther(cost), "+ treasury fee", ethers.formatEther(treasury));
// 4) 真实买入
console.log("> mintCollateralToExactOt(1000 OT, tokenId=1)...");
try {
const tx = await market.mintCollateralToExactOt(signer.address, OUTCOME, OT, "0x", { gasLimit: 2000000 });
const receipt = await tx.wait();
console.log(" BUY SUCCESS tx:", tx.hash, "status:", receipt.status);
console.log(" gasUsed:", receipt.gasUsed.toString());
} catch (e) {
console.log(" BUY FAILED:", e.shortMessage || e.message);
process.exitCode = 1;
return;
}
// 5) 检查 OT 余额并真实卖出
const otBal = await market.balanceOf(signer.address, OUTCOME);
console.log("OT balance:", ethers.formatEther(otBal));
console.log("> redeemExactOtToCollateral(1000 OT)...");
try {
const tx = await market.redeemExactOtToCollateral(signer.address, OUTCOME, OT, "0x", { gasLimit: 2000000 });
const receipt = await tx.wait();
console.log(" SELL SUCCESS tx:", tx.hash, "status:", receipt.status);
} catch (e) {
console.log(" SELL FAILED:", e.shortMessage || e.message);
process.exitCode = 1;
}
}
main().catch((e) => {
console.error(e);
process.exitCode = 1;
});