From b6d659991f67e1ba39ee3d9df3077c6b62359dd7 Mon Sep 17 00:00:00 2001 From: Michael Buntarman Date: Tue, 13 Jan 2026 15:16:52 +0700 Subject: [PATCH 1/2] feat: bridge with hoodi tt2 non-custodial contract --- .../migrations/erc20-bridge/000-extension.sql | 18 ++++- .../migrations/erc20-bridge/001-actions.sql | 76 ++++++++++++++++--- .../erc20-bridge/003-disable-hoodi.prod.sql | 8 +- .../004-withdrawal-proof-action.sql | 6 +- .../erc20_bridge_withdrawal_proof_test.go | 32 ++++---- tests/streams/hoodi_withdrawal_fee_test.go | 18 ++--- 6 files changed, 115 insertions(+), 43 deletions(-) diff --git a/internal/migrations/erc20-bridge/000-extension.sql b/internal/migrations/erc20-bridge/000-extension.sql index c435f281b..52de7201d 100644 --- a/internal/migrations/erc20-bridge/000-extension.sql +++ b/internal/migrations/erc20-bridge/000-extension.sql @@ -19,9 +19,23 @@ USE erc20 { distribution_period: '10m' } AS sepolia_bridge; --- The following is for test environments where the hoodi bridge is used. Please comment for production and use the above. +-- The following is for test environments where the hoodi bridges are used. Please comment for production and use the above. +-- First hoodi bridge: Test Token (TT) +-- Token: 0x263ce78fef26600e4e428cebc91c2a52484b4fbf +-- Proxy: 0x878d6aaeb6e746033f50b8dc268d54b4631554e7 +-- Explorer: https://hoodi.etherscan.io/address/0x878d6aaeb6e746033f50b8dc268d54b4631554e7 USE erc20 { chain: 'hoodi', escrow: '0x878d6aaeb6e746033f50b8dc268d54b4631554e7', distribution_period: '10m' -} AS hoodi_bridge; \ No newline at end of file +} AS hoodi_tt; + +-- Second hoodi bridge: Test Token 2 (TT2) +-- Token: 0x1591DeAa21710E0BA6CC1b15F49620C9F65B2dEd +-- Proxy: 0x9BD843A3ce718FE639e9968860B933b026784687 +-- Explorer: https://hoodi.etherscan.io/address/0x9BD843A3ce718FE639e9968860B933b026784687 +USE erc20 { + chain: 'hoodi', + escrow: '0x9BD843A3ce718FE639e9968860B933b026784687', + distribution_period: '10m' +} AS hoodi_tt2; \ No newline at end of file diff --git a/internal/migrations/erc20-bridge/001-actions.sql b/internal/migrations/erc20-bridge/001-actions.sql index 1250fd91a..f3564cfbc 100644 --- a/internal/migrations/erc20-bridge/001-actions.sql +++ b/internal/migrations/erc20-bridge/001-actions.sql @@ -1,5 +1,5 @@ --- HOODI TESTNET -CREATE OR REPLACE ACTION hoodi_get_erc20_bridge_info() +-- HOODI TESTNET - Test Token (TT) +CREATE OR REPLACE ACTION hoodi_tt_get_erc20_bridge_info() PUBLIC VIEW RETURNS ( chain TEXT, escrow TEXT, @@ -11,23 +11,23 @@ PUBLIC VIEW RETURNS ( synced_at INT8, enabled BOOLEAN ) { - FOR $row IN hoodi_bridge.info() { + FOR $row IN hoodi_tt.info() { RETURN $row.chain, $row.escrow, $row.epoch_period, $row.erc20, $row.decimals, $row.balance, $row.synced, $row.synced_at, $row.enabled; } }; -CREATE OR REPLACE ACTION hoodi_wallet_balance($wallet_address TEXT) PUBLIC VIEW RETURNS (balance NUMERIC(78, 0)) { - $balance := hoodi_bridge.balance($wallet_address); +CREATE OR REPLACE ACTION hoodi_tt_wallet_balance($wallet_address TEXT) PUBLIC VIEW RETURNS (balance NUMERIC(78, 0)) { + $balance := hoodi_tt.balance($wallet_address); RETURN $balance; }; -CREATE OR REPLACE ACTION hoodi_bridge_tokens($recipient TEXT DEFAULT NULL, $amount TEXT) PUBLIC { +CREATE OR REPLACE ACTION hoodi_tt_bridge_tokens($recipient TEXT DEFAULT NULL, $amount TEXT) PUBLIC { -- ===== FEE COLLECTION (NO EXEMPTION - USER-FACING OPERATION) ===== $withdrawal_fee := '40000000000000000000'::NUMERIC(78, 0); -- 40 TRUF with 18 decimals $withdrawal_amount := $amount::NUMERIC(78, 0); $total_required := $withdrawal_amount + $withdrawal_fee; - $caller_balance := COALESCE(hoodi_bridge.balance(@caller), 0::NUMERIC(78, 0)); + $caller_balance := COALESCE(hoodi_tt.balance(@caller), 0::NUMERIC(78, 0)); IF $caller_balance < $total_required { ERROR('Insufficient balance for withdrawal. Required: ' || @@ -40,13 +40,71 @@ CREATE OR REPLACE ACTION hoodi_bridge_tokens($recipient TEXT DEFAULT NULL, $amou ERROR('Leader address not available for fee transfer'); } $leader_hex TEXT := encode(@leader_sender, 'hex')::TEXT; - hoodi_bridge.transfer($leader_hex, $withdrawal_fee); + hoodi_tt.transfer($leader_hex, $withdrawal_fee); -- ===== END FEE COLLECTION ===== $bridge_recipient TEXT := LOWER(COALESCE($recipient, @caller)); -- Execute withdrawal using the bridge extension - hoodi_bridge.bridge($bridge_recipient, $withdrawal_amount); + hoodi_tt.bridge($bridge_recipient, $withdrawal_amount); + + record_transaction_event( + 5, + $withdrawal_fee, + '0x' || $leader_hex, + NULL + ); +}; + +-- HOODI TESTNET - Test Token 2 (TT2) +CREATE OR REPLACE ACTION hoodi_tt2_get_erc20_bridge_info() +PUBLIC VIEW RETURNS ( + chain TEXT, + escrow TEXT, + epoch_period TEXT, + erc20 TEXT, + decimals INT, + balance NUMERIC(78, 0), + synced BOOLEAN, + synced_at INT8, + enabled BOOLEAN +) { + FOR $row IN hoodi_tt2.info() { + RETURN $row.chain, $row.escrow, $row.epoch_period, $row.erc20, $row.decimals, $row.balance, $row.synced, $row.synced_at, $row.enabled; + } +}; + +CREATE OR REPLACE ACTION hoodi_tt2_wallet_balance($wallet_address TEXT) PUBLIC VIEW RETURNS (balance NUMERIC(78, 0)) { + $balance := hoodi_tt2.balance($wallet_address); + RETURN $balance; +}; + +CREATE OR REPLACE ACTION hoodi_tt2_bridge_tokens($recipient TEXT DEFAULT NULL, $amount TEXT) PUBLIC { + -- ===== FEE COLLECTION (NO EXEMPTION - USER-FACING OPERATION) ===== + $withdrawal_fee := '40000000000000000000'::NUMERIC(78, 0); -- 40 TRUF with 18 decimals + $withdrawal_amount := $amount::NUMERIC(78, 0); + $total_required := $withdrawal_amount + $withdrawal_fee; + + $caller_balance := COALESCE(hoodi_tt2.balance(@caller), 0::NUMERIC(78, 0)); + + IF $caller_balance < $total_required { + ERROR('Insufficient balance for withdrawal. Required: ' || + ($total_required / '1000000000000000000'::NUMERIC(78, 0))::TEXT || + ' TRUF (' || $withdrawal_amount::TEXT || ' wei withdrawal + ' || + ($withdrawal_fee / '1000000000000000000'::NUMERIC(78, 0))::TEXT || ' TRUF fee)'); + } + + IF @leader_sender IS NULL { + ERROR('Leader address not available for fee transfer'); + } + $leader_hex TEXT := encode(@leader_sender, 'hex')::TEXT; + hoodi_tt2.transfer($leader_hex, $withdrawal_fee); + -- ===== END FEE COLLECTION ===== + + $bridge_recipient TEXT := LOWER(COALESCE($recipient, @caller)); + + -- Execute withdrawal using the bridge extension + hoodi_tt2.bridge($bridge_recipient, $withdrawal_amount); record_transaction_event( 5, diff --git a/internal/migrations/erc20-bridge/003-disable-hoodi.prod.sql b/internal/migrations/erc20-bridge/003-disable-hoodi.prod.sql index bda55f27a..0df787d48 100644 --- a/internal/migrations/erc20-bridge/003-disable-hoodi.prod.sql +++ b/internal/migrations/erc20-bridge/003-disable-hoodi.prod.sql @@ -1,7 +1,7 @@ --- Disable and remove Hoodi bridge instance --- This migration removes the hoodi_bridge extension to allow fresh deployment with new escrow +-- Disable and remove Hoodi bridge instance (Test Token) +-- This migration removes the hoodi_tt extension to allow fresh deployment with new escrow -- -- UNUSE will properly clean up the namespace even if the instance is already disabled. --- Use this migration to rollback to a clean state before re-adding the hoodi_bridge with new parameters. +-- Use this migration to rollback to a clean state before re-adding the hoodi_tt with new parameters. -UNUSE hoodi_bridge; +UNUSE hoodi_tt; diff --git a/internal/migrations/erc20-bridge/004-withdrawal-proof-action.sql b/internal/migrations/erc20-bridge/004-withdrawal-proof-action.sql index 797355c5d..b034db97c 100644 --- a/internal/migrations/erc20-bridge/004-withdrawal-proof-action.sql +++ b/internal/migrations/erc20-bridge/004-withdrawal-proof-action.sql @@ -1,9 +1,9 @@ --- Withdrawal Proof Action for Hoodi Non-Custodial Bridge +-- Withdrawal Proof Action for Hoodi Non-Custodial Bridge (Test Token) -- This action exposes the list_wallet_rewards precompile as a public action. -- Returns merkle proofs AND validator signatures - everything needed for withdrawal. -- Returns ALL confirmed epochs, not just first one (uses RETURN NEXT) -- Epochs filtered by withdrawals table (only unclaimed epochs returned) -CREATE OR REPLACE ACTION hoodi_get_withdrawal_proof($wallet_address TEXT) +CREATE OR REPLACE ACTION hoodi_tt_get_withdrawal_proof($wallet_address TEXT) PUBLIC VIEW RETURNS TABLE ( chain TEXT, chain_id TEXT, @@ -18,7 +18,7 @@ PUBLIC VIEW RETURNS TABLE ( ) { -- with_pending = false means only return confirmed epochs (ready for withdrawal) -- Returns ALL confirmed epochs ordered by height DESC (newest first) - FOR $row IN hoodi_bridge.list_wallet_rewards($wallet_address, false) { + FOR $row IN hoodi_tt.list_wallet_rewards($wallet_address, false) { -- Return each row (don't exit loop!) RETURN NEXT $row.chain, $row.chain_id, $row.contract, $row.created_at, $row.param_recipient, $row.param_amount, $row.param_block_hash, diff --git a/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go b/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go index 58afd3933..a19fc5463 100644 --- a/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go +++ b/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go @@ -21,29 +21,29 @@ const ( // Real Hoodi chain and addresses (from migrations) MigrationHoodiChain = "hoodi" MigrationHoodiEscrow = "0x878d6aaeb6e746033f50b8dc268d54b4631554e7" - MigrationHoodiAlias = "hoodi_bridge" // Alias from migration 000-extension.sql + MigrationHoodiAlias = "hoodi_tt" // Alias from migration 000-extension.sql ) -// TestHoodiGetWithdrawalProofAction tests the public hoodi_get_withdrawal_proof action. -// This test uses the migration-registered hoodi_bridge instance (not a test-specific instance). +// TestHoodiGetWithdrawalProofAction tests the public hoodi_tt_get_withdrawal_proof action. +// This test uses the migration-registered hoodi_tt instance (not a test-specific instance). // // Test flow: // 1) Seed data into migration-registered hoodi_bridge instance // 2) User deposits and withdraws // 3) Finalize and confirm epoch -// 4) Call public action hoodi_get_withdrawal_proof +// 4) Call public action hoodi_tt_get_withdrawal_proof // 5) Verify returned merkle proof structure // // This validates the full end-to-end public API that users will call. func TestHoodiGetWithdrawalProofAction(t *testing.T) { - seedAndRun(t, "hoodi_get_withdrawal_proof_action", func(ctx context.Context, platform *kwilTesting.Platform) error { - // The hoodi_bridge instance is already created by migrations (000-extension.sql) + seedAndRun(t, "hoodi_tt_get_withdrawal_proof_action", func(ctx context.Context, platform *kwilTesting.Platform) error { + // The hoodi_tt instance is already created by migrations (000-extension.sql) // We just need to seed it with test data testUser := "0xf9820f9143699cac6f662b19a4b29e13c9393783" testAmount := "100000000000000000000" // 100 tokens - // The hoodi_bridge instance already exists from migrations + // The hoodi_tt instance already exists from migrations // Need to sync it to database AND load into singleton _, err := erc20shim.ForTestingForceSyncInstance( ctx, platform, @@ -52,7 +52,7 @@ func TestHoodiGetWithdrawalProofAction(t *testing.T) { "0x0000000000000000000000000000000000000001", // Fake ERC20 for testing 18, ) - require.NoError(t, err, "failed to sync hoodi_bridge instance") + require.NoError(t, err, "failed to sync hoodi_tt instance") // Load DB instances into singleton err = erc20shim.ForTestingInitializeExtension(ctx, platform) @@ -106,7 +106,7 @@ func TestHoodiGetWithdrawalProofAction(t *testing.T) { ) require.NoError(t, err, "failed to add validator signature") - // Call the PUBLIC ACTION hoodi_get_withdrawal_proof + // Call the PUBLIC ACTION hoodi_tt_get_withdrawal_proof // This is the action users will call in production engineCtx = engCtx(ctx, platform, "0x0000000000000000000000000000000000000000", 3, false) @@ -117,7 +117,7 @@ func TestHoodiGetWithdrawalProofAction(t *testing.T) { var proofs [][]byte var signatures [][]byte - r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_get_withdrawal_proof", + r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_tt_get_withdrawal_proof", []any{testUser}, // Just wallet address parameter func(row *common.Row) error { proofRows++ @@ -216,7 +216,7 @@ func TestHoodiGetWithdrawalProofAction(t *testing.T) { } t.Logf("Total validator signatures: %d", len(signatures)) - t.Logf("✅ Public action hoodi_get_withdrawal_proof works correctly") + t.Logf("✅ Public action hoodi_tt_get_withdrawal_proof works correctly") t.Logf(" Chain: %s", chain) t.Logf(" ChainID: %s", chainID) t.Logf(" Contract: %s", contract) @@ -230,7 +230,7 @@ func TestHoodiGetWithdrawalProofAction(t *testing.T) { // TestHoodiGetWithdrawalProofNoPending tests that pending epochs are not returned. func TestHoodiGetWithdrawalProofNoPending(t *testing.T) { - seedAndRun(t, "hoodi_get_withdrawal_proof_no_pending", func(ctx context.Context, platform *kwilTesting.Platform) error { + seedAndRun(t, "hoodi_tt_get_withdrawal_proof_no_pending", func(ctx context.Context, platform *kwilTesting.Platform) error { testUser := "0xabc0000000000000000000000000000000000001" testAmount := "50000000000000000000" @@ -280,7 +280,7 @@ func TestHoodiGetWithdrawalProofNoPending(t *testing.T) { // Call public action engineCtx = engCtx(ctx, platform, "0x0000000000000000000000000000000000000000", 3, false) var proofRows int - r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_get_withdrawal_proof", + r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_tt_get_withdrawal_proof", []any{testUser}, func(row *common.Row) error { proofRows++ @@ -304,7 +304,7 @@ func TestHoodiGetWithdrawalProofNoPending(t *testing.T) { // Note: Testing multiple EPOCHS requires complex timing logic not yet in test infrastructure. // This test validates that multiple users can each retrieve their withdrawal proofs correctly. func TestHoodiGetWithdrawalProofMultipleUsers(t *testing.T) { - seedAndRun(t, "hoodi_get_withdrawal_proof_multiple_users", func(ctx context.Context, platform *kwilTesting.Platform) error { + seedAndRun(t, "hoodi_tt_get_withdrawal_proof_multiple_users", func(ctx context.Context, platform *kwilTesting.Platform) error { userA := "0xabc0000000000000000000000000000000000001" userB := "0xabc0000000000000000000000000000000000002" amount100 := "100000000000000000000" @@ -405,7 +405,7 @@ func TestHoodiGetWithdrawalProofMultipleUsers(t *testing.T) { var proofRowsA int var amountA string - r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_get_withdrawal_proof", + r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_tt_get_withdrawal_proof", []any{userA}, func(row *common.Row) error { proofRowsA++ @@ -424,7 +424,7 @@ func TestHoodiGetWithdrawalProofMultipleUsers(t *testing.T) { var proofRowsB int var amountB string - r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_get_withdrawal_proof", + r, err = platform.Engine.Call(engineCtx, platform.DB, "", "hoodi_tt_get_withdrawal_proof", []any{userB}, func(row *common.Row) error { proofRowsB++ diff --git a/tests/streams/hoodi_withdrawal_fee_test.go b/tests/streams/hoodi_withdrawal_fee_test.go index 79295bd58..10cfb3b3b 100644 --- a/tests/streams/hoodi_withdrawal_fee_test.go +++ b/tests/streams/hoodi_withdrawal_fee_test.go @@ -25,7 +25,7 @@ const ( testHoodiChain = "hoodi" testHoodiEscrow = "0x878d6aaeb6e746033f50b8dc268d54b4631554e7" // Real Hoodi bridge proxy testHoodiERC20 = "0x263ce78fef26600e4e428cebc91c2a52484b4fbf" // Real TRUF token on Hoodi - testHoodiExtensionName = "hoodi_bridge" // Extension name from migrations + testHoodiExtensionName = "hoodi_tt" // Extension name from migrations hoodiWithdrawalFee = "40000000000000000000" // 40 TRUF with 18 decimals ) @@ -45,7 +45,7 @@ func mustParseHoodiBigInt(s string) *big.Int { } // TestHoodiWithdrawalFees is the main test suite for Hoodi bridge withdrawal fees -// This test validates the hoodi_bridge_tokens action defined in 001-actions.sql +// This test validates the hoodi_tt_bridge_tokens action defined in 001-actions.sql func TestHoodiWithdrawalFees(t *testing.T) { testutils.RunSchemaTest(t, kwilTesting.SchemaTest{ Name: "HOODI_WITHDRAWAL_FEE01_WithdrawalFees", @@ -71,7 +71,7 @@ func setupHoodiWithdrawalTestEnvironment(t *testing.T) func(ctx context.Context, platform.Deployer = systemAdmin.Bytes() // Sync and initialize Hoodi bridge extension - // The hoodi_bridge instance is created by migrations (000-extension.sql) + // The hoodi_tt instance is created by migrations (000-extension.sql) // ForTestingForceSyncInstance ensures it's synced in DB _, err := erc20shim.ForTestingForceSyncInstance( ctx, @@ -124,7 +124,7 @@ func testHoodiWithdrawalPaysFee(t *testing.T) func(ctx context.Context, platform // Withdraw 10 TRUF (should deduct 50 TRUF total: 10 withdrawal + 40 fee) withdrawAmount := "10000000000000000000" // 10 TRUF err = executeHoodiWithdrawalWithLeader(ctx, platform, userAddr, pub, userAddr.Address(), withdrawAmount) - require.NoError(t, err, "hoodi_bridge_tokens should succeed") + require.NoError(t, err, "hoodi_tt_bridge_tokens should succeed") // Verify balance decreased by 50 TRUF (10 TRUF withdrawal + 40 TRUF fee) finalBalance, err := getHoodiBalance(ctx, platform, userAddr.Address()) @@ -164,7 +164,7 @@ func testHoodiWithdrawalInsufficientBalance(t *testing.T) func(ctx context.Conte // Try to withdraw 10 TRUF (should fail - needs 50 TRUF total) withdrawAmount := "10000000000000000000" // 10 TRUF err = executeHoodiWithdrawalWithLeader(ctx, platform, userAddr, pub, userAddr.Address(), withdrawAmount) - require.Error(t, err, "hoodi_bridge_tokens should fail with insufficient balance") + require.Error(t, err, "hoodi_tt_bridge_tokens should fail with insufficient balance") require.Contains(t, err.Error(), "Insufficient balance for withdrawal", "error should mention insufficient balance, got: %v", err) @@ -255,10 +255,10 @@ func testHoodiWithdrawalFeeRecordedInLedger(t *testing.T) func(ctx context.Conte // Withdraw 10 TRUF withdrawAmount := "10000000000000000000" // 10 TRUF err = executeHoodiWithdrawalWithLeader(ctx, platform, userAddr, pub, userAddr.Address(), withdrawAmount) - require.NoError(t, err, "hoodi_bridge_tokens should succeed") + require.NoError(t, err, "hoodi_tt_bridge_tokens should succeed") // Query transaction_events table to verify fee was recorded - // The hoodi_bridge_tokens action calls record_transaction_event(5, $withdrawal_fee, leader, NULL) + // The hoodi_tt_bridge_tokens action calls record_transaction_event(5, $withdrawal_fee, leader, NULL) // Table schema: method_id (INT), fee_amount (NUMERIC), fee_recipient (TEXT) query := `SELECT method_id, fee_amount::TEXT, fee_recipient FROM transaction_events WHERE method_id = 5 AND fee_recipient IS NOT NULL @@ -366,12 +366,12 @@ func callHoodiWithdrawalAction(ctx context.Context, platform *kwilTesting.Platfo } engineCtx := &common.EngineContext{TxContext: tx} - // Call hoodi_bridge_tokens action (defined in 001-actions.sql) + // Call hoodi_tt_bridge_tokens action (defined in 001-actions.sql) res, err := platform.Engine.Call( engineCtx, platform.DB, "", - "hoodi_bridge_tokens", // Hoodi-specific action with 40 TRUF fee + "hoodi_tt_bridge_tokens", // Hoodi TT-specific action with 40 TRUF fee []any{recipient, amount}, func(row *common.Row) error { return nil }, ) From 4099b9bad7ea81fb4a49329643e4f7951bb7fea2 Mon Sep 17 00:00:00 2001 From: Michael Buntarman Date: Tue, 13 Jan 2026 15:44:07 +0700 Subject: [PATCH 2/2] chore: apply suggestion --- .../erc20/erc20_bridge_withdrawal_proof_test.go | 2 +- tests/streams/hoodi_withdrawal_fee_test.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go b/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go index a19fc5463..c2d7e18c8 100644 --- a/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go +++ b/tests/extensions/erc20/erc20_bridge_withdrawal_proof_test.go @@ -28,7 +28,7 @@ const ( // This test uses the migration-registered hoodi_tt instance (not a test-specific instance). // // Test flow: -// 1) Seed data into migration-registered hoodi_bridge instance +// 1) Seed data into migration-registered hoodi_tt instance // 2) User deposits and withdraws // 3) Finalize and confirm epoch // 4) Call public action hoodi_tt_get_withdrawal_proof diff --git a/tests/streams/hoodi_withdrawal_fee_test.go b/tests/streams/hoodi_withdrawal_fee_test.go index 10cfb3b3b..3db5d1297 100644 --- a/tests/streams/hoodi_withdrawal_fee_test.go +++ b/tests/streams/hoodi_withdrawal_fee_test.go @@ -96,7 +96,7 @@ func setupHoodiWithdrawalTestEnvironment(t *testing.T) func(ctx context.Context, } } -// Test 1: hoodi_bridge_tokens pays 40 TRUF fee +// Test 1: hoodi_tt_bridge_tokens pays 40 TRUF fee func testHoodiWithdrawalPaysFee(t *testing.T) func(ctx context.Context, platform *kwilTesting.Platform) error { return func(ctx context.Context, platform *kwilTesting.Platform) error { // Re-initialize extension in this test (singleton might have been reset) @@ -137,7 +137,7 @@ func testHoodiWithdrawalPaysFee(t *testing.T) func(ctx context.Context, platform "Balance should decrease by 50 TRUF (10 withdrawal + 40 fee), expected %s but got %s", expectedBalance, finalBalance) - t.Logf("✅ hoodi_bridge_tokens correctly deducted 50 TRUF (10 withdrawal + 40 fee)") + t.Logf("✅ hoodi_tt_bridge_tokens correctly deducted 50 TRUF (10 withdrawal + 40 fee)") return nil } } @@ -168,7 +168,7 @@ func testHoodiWithdrawalInsufficientBalance(t *testing.T) func(ctx context.Conte require.Contains(t, err.Error(), "Insufficient balance for withdrawal", "error should mention insufficient balance, got: %v", err) - t.Logf("✅ hoodi_bridge_tokens correctly rejects insufficient balance (30 TRUF < 50 TRUF needed)") + t.Logf("✅ hoodi_tt_bridge_tokens correctly rejects insufficient balance (30 TRUF < 50 TRUF needed)") return nil } } @@ -212,7 +212,7 @@ func testHoodiWithdrawalLeaderReceivesFees(t *testing.T) func(ctx context.Contex // Withdraw 10 TRUF with specific leader withdrawAmount := "10000000000000000000" // 10 TRUF err = executeHoodiWithdrawalWithLeader(ctx, platform, userAddr, pub, userAddr.Address(), withdrawAmount) - require.NoError(t, err, "hoodi_bridge_tokens with leader should succeed") + require.NoError(t, err, "hoodi_tt_bridge_tokens with leader should succeed") // Verify leader balance increased by 40 TRUF finalLeaderBalance, err := getHoodiBalance(ctx, platform, leaderAddr) @@ -351,7 +351,7 @@ func getHoodiBalance(ctx context.Context, platform *kwilTesting.Platform, wallet return balance, nil } -// callHoodiWithdrawalAction calls the hoodi_bridge_tokens action +// callHoodiWithdrawalAction calls the hoodi_tt_bridge_tokens action func callHoodiWithdrawalAction(ctx context.Context, platform *kwilTesting.Platform, signer *util.EthereumAddress, leaderPub *crypto.Secp256k1PublicKey, recipient string, amount string) error { tx := &common.TxContext{ Ctx: ctx,