diff --git a/frontend/src/components/LPPanel.tsx b/frontend/src/components/LPPanel.tsx
index e63f39a..b66277f 100644
--- a/frontend/src/components/LPPanel.tsx
+++ b/frontend/src/components/LPPanel.tsx
@@ -60,6 +60,7 @@ export function LPPanel() {
slippage: '0.5',
})
const [activeTab, setActiveTab] = useState<'add' | 'remove' | 'swap'>('add')
+ const [showBoundaryTest, setShowBoundaryTest] = useState(false)
// Read pool data
const { data: ytLPBalance, refetch: refetchBalance } = useReadContract({
@@ -295,6 +296,88 @@ export function LPPanel() {
return token?.symbol || 'Unknown'
}
+ // Boundary test function
+ const runBoundaryTest = (testType: string) => {
+ if (!address) return
+ recordTx('test', undefined, 'LP')
+
+ switch (testType) {
+ case 'add_zero':
+ // 添加流动性金额为0
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'addLiquidity',
+ args: [CONTRACTS.VAULTS.YT_A, BigInt(0), BigInt(0), BigInt(0)],
+ })
+ break
+ case 'add_exceed_balance':
+ // 添加超过余额
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'addLiquidity',
+ args: [CONTRACTS.VAULTS.YT_A, parseUnits('999999999', 18), BigInt(0), BigInt(0)],
+ })
+ break
+ case 'remove_zero':
+ // 移除流动性金额为0
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'removeLiquidity',
+ args: [CONTRACTS.VAULTS.YT_A, BigInt(0), BigInt(0), address],
+ })
+ break
+ case 'remove_exceed_balance':
+ // 移除超过ytLP余额
+ const exceedAmount = ytLPBalance ? ytLPBalance + parseUnits('999999', 18) : parseUnits('999999999', 18)
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'removeLiquidity',
+ args: [CONTRACTS.VAULTS.YT_A, exceedAmount, BigInt(0), address],
+ })
+ break
+ case 'remove_high_minout':
+ // 移除时minOut过高
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'removeLiquidity',
+ args: [CONTRACTS.VAULTS.YT_A, parseUnits('1', 18), parseUnits('999999999', 18), address],
+ })
+ break
+ case 'swap_zero':
+ // 互换金额为0
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'swapYT',
+ args: [CONTRACTS.VAULTS.YT_A, CONTRACTS.VAULTS.YT_B, BigInt(0), BigInt(0), address],
+ })
+ break
+ case 'swap_same_token':
+ // 相同代币互换
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'swapYT',
+ args: [CONTRACTS.VAULTS.YT_A, CONTRACTS.VAULTS.YT_A, parseUnits('1', 18), BigInt(0), address],
+ })
+ break
+ case 'swap_exceed_balance':
+ // 互换超过余额
+ writeContract({
+ address: CONTRACTS.YT_REWARD_ROUTER,
+ abi: YT_REWARD_ROUTER_ABI,
+ functionName: 'swapYT',
+ args: [CONTRACTS.VAULTS.YT_A, CONTRACTS.VAULTS.YT_B, parseUnits('999999999', 18), BigInt(0), address],
+ })
+ break
+ }
+ }
+
// Calculate cooldown remaining time
const getCooldownRemaining = () => {
if (!lastAddedAt || !cooldownDuration) return 0
@@ -615,6 +698,122 @@ export function LPPanel() {
)}
+ {/* 边界测试区域 */}
+
+
setShowBoundaryTest(!showBoundaryTest)} style={{ cursor: 'pointer' }}>
+
{t('test.boundaryTests')} {showBoundaryTest ? '[-]' : '[+]'}
+
+
+ {showBoundaryTest && (
+ <>
+
{t('lp.boundaryHint')}
+
+ {/* 冷却时间状态 */}
+
+ {t('lp.cooldownRemaining')}:
+ 0 ? 'text-warning' : 'text-success'}>
+ {formatCooldown(getCooldownRemaining())}
+
+ {t('lp.yourBalance')}:
+ {ytLPBalance ? formatUnits(ytLPBalance, 18) : '0'} ytLP
+
+
+
+ {/* 添加流动性边界测试 */}
+
+
+ {t('lp.testAddZero')}
+ InvalidAmount
+
+
{t('lp.testAddZeroDesc')}
+
+
+
+
+
+ {t('lp.testAddExceed')}
+ InsufficientBalance
+
+
{t('lp.testAddExceedDesc')}
+
+
+
+ {/* 移除流动性边界测试 */}
+
+
+ {t('lp.testRemoveZero')}
+ InvalidAmount
+
+
{t('lp.testRemoveZeroDesc')}
+
+
+
+
+
+ {t('lp.testRemoveExceed')}
+ InsufficientBalance
+
+
{t('lp.testRemoveExceedDesc')}
+
+
+
+
+
+ {t('lp.testRemoveHighMinout')}
+ InsufficientOutput
+
+
{t('lp.testRemoveHighMinoutDesc')}
+
+
+
+ {/* 代币互换边界测试 */}
+
+
+ {t('lp.testSwapZero')}
+ InvalidAmount
+
+
{t('lp.testSwapZeroDesc')}
+
+
+
+
+
+ {t('lp.testSwapSame')}
+ SameToken
+
+
{t('lp.testSwapSameDesc')}
+
+
+
+
+
+ {t('lp.testSwapExceed')}
+ InsufficientBalance
+
+
{t('lp.testSwapExceedDesc')}
+
+
+
+ >
+ )}
+
+
{/* Transaction History */}
diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json
index cad91d9..5730fd9 100644
--- a/frontend/src/i18n/locales/en.json
+++ b/frontend/src/i18n/locales/en.json
@@ -178,6 +178,23 @@
"swap": "Swap",
"cooldownNotPassed": "Cooldown not passed, please try later",
"insufficientOutput": "Insufficient output amount",
- "cooldownWarning": "Cooldown remaining {{time}}, cannot remove liquidity yet"
+ "cooldownWarning": "Cooldown remaining {{time}}, cannot remove liquidity yet",
+ "boundaryHint": "These tests are designed to trigger LP contract errors. Expected errors are shown for each test.",
+ "testAddZero": "Add Liquidity Zero",
+ "testAddZeroDesc": "Test addLiquidity(token, 0, 0, 0)",
+ "testAddExceed": "Add Exceed Balance",
+ "testAddExceedDesc": "Add liquidity exceeding token balance",
+ "testRemoveZero": "Remove Liquidity Zero",
+ "testRemoveZeroDesc": "Test removeLiquidity(token, 0, 0, receiver)",
+ "testRemoveExceed": "Remove Exceed Balance",
+ "testRemoveExceedDesc": "Remove liquidity exceeding ytLP balance",
+ "testRemoveHighMinout": "Remove High MinOut",
+ "testRemoveHighMinoutDesc": "Set impossible minimum output amount",
+ "testSwapZero": "Swap Amount Zero",
+ "testSwapZeroDesc": "Test swapYT(tokenIn, tokenOut, 0, 0, receiver)",
+ "testSwapSame": "Swap Same Token",
+ "testSwapSameDesc": "Test swapYT(YT-A, YT-A, amount, 0, receiver)",
+ "testSwapExceed": "Swap Exceed Balance",
+ "testSwapExceedDesc": "Swap amount exceeding token balance"
}
}
diff --git a/frontend/src/i18n/locales/zh.json b/frontend/src/i18n/locales/zh.json
index 987909a..70e94a4 100644
--- a/frontend/src/i18n/locales/zh.json
+++ b/frontend/src/i18n/locales/zh.json
@@ -178,6 +178,23 @@
"swap": "交换",
"cooldownNotPassed": "冷却期未过,请稍后再试",
"insufficientOutput": "输出金额不足",
- "cooldownWarning": "冷却期剩余 {{time}},暂时无法移除流动性"
+ "cooldownWarning": "冷却期剩余 {{time}},暂时无法移除流动性",
+ "boundaryHint": "这些测试旨在触发LP合约错误。每个测试都显示了预期的错误类型。",
+ "testAddZero": "添加流动性为0",
+ "testAddZeroDesc": "测试 addLiquidity(token, 0, 0, 0)",
+ "testAddExceed": "添加超过余额",
+ "testAddExceedDesc": "添加流动性金额超过代币余额",
+ "testRemoveZero": "移除流动性为0",
+ "testRemoveZeroDesc": "测试 removeLiquidity(token, 0, 0, receiver)",
+ "testRemoveExceed": "移除超过余额",
+ "testRemoveExceedDesc": "移除流动性金额超过ytLP余额",
+ "testRemoveHighMinout": "移除minOut过高",
+ "testRemoveHighMinoutDesc": "设置不可能达到的最小输出金额",
+ "testSwapZero": "互换金额为0",
+ "testSwapZeroDesc": "测试 swapYT(tokenIn, tokenOut, 0, 0, receiver)",
+ "testSwapSame": "相同代币互换",
+ "testSwapSameDesc": "测试 swapYT(YT-A, YT-A, amount, 0, receiver)",
+ "testSwapExceed": "互换超过余额",
+ "testSwapExceedDesc": "互换金额超过代币余额"
}
}