Skip to content

Commit f4c768b

Browse files
committed
testing
1 parent 029b4dd commit f4c768b

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
// SPDX-License-Identifier: -- BCOM --
2+
3+
pragma solidity =0.8.25;
4+
5+
import "forge-std/Test.sol";
6+
import "forge-std/console.sol";
7+
8+
// Balancer V3 interfaces
9+
import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol";
10+
import { IRouter } from "@balancer-labs/v3-interfaces/contracts/vault/IRouter.sol";
11+
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
12+
import {
13+
SwapKind
14+
} from "@balancer-labs/v3-interfaces/contracts/vault/VaultTypes.sol";
15+
16+
// Test for live DiscountHook_V3 contract
17+
contract DiscountHook_V3_Live_Test is Test {
18+
// Mainnet addresses
19+
IVault constant VAULT = IVault(0xbA1333333333a1BA1108E8412f11850A5C319bA9);
20+
IRouter constant ROUTER = IRouter(payable(0xAE563E3f8219521950555F5962419C8919758Ea2));
21+
22+
// Live contracts
23+
address constant DISCOUNT_HOOK = 0x4F4F5347EC267E18787e56efb654D4d7A3e0C0E7;
24+
address constant DISCOUNT_CONFIG = 0x7AffEf8867d0f00eF6A3793EC8f0c3ba9c568AF2;
25+
address constant POOL_ADDRESS = 0x33832529ca354536728A2f2515E4E2106A8D8afA;
26+
27+
// Token addresses (WETH/VERSE pool)
28+
IERC20 constant VERSE = IERC20(0x249cA82617eC3DfB2589c4c17ab7EC9765350a18);
29+
IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
30+
31+
// Test accounts
32+
address alice = makeAddr("alice");
33+
address bob = makeAddr("bob");
34+
35+
// Whale addresses for getting tokens
36+
address constant VERSE_WHALE = 0x249cA82617eC3DfB2589c4c17ab7EC9765350a18; // Token contract itself
37+
address constant WETH_WHALE = 0x8EB8a3b98659Cce290402893d0123abb75E3ab28; // Known WETH holder
38+
39+
struct SwapResult {
40+
uint256 amountIn;
41+
uint256 amountOut;
42+
uint256 swapFeeAmount;
43+
uint256 effectiveFeePercentage;
44+
}
45+
46+
function setUp() public {
47+
// Fork mainnet using the configured RPC endpoint
48+
vm.createSelectFork("mainnet");
49+
50+
// Setup test accounts with ETH
51+
vm.deal(alice, 10 ether);
52+
vm.deal(bob, 10 ether);
53+
54+
// Give Alice some VERSE tokens (she will get discount)
55+
vm.prank(VERSE_WHALE);
56+
VERSE.transfer(alice, 1000e18);
57+
58+
// Give both users some WETH and USDC for testing
59+
_setupTokenBalances();
60+
61+
console.log("=== Test Setup Complete ===");
62+
console.log("Alice VERSE balance:", VERSE.balanceOf(alice) / 1e18, "VERSE");
63+
console.log("Bob VERSE balance:", VERSE.balanceOf(bob) / 1e18, "VERSE");
64+
console.log("Alice WETH balance:", WETH.balanceOf(alice) / 1e18, "WETH");
65+
console.log("Bob WETH balance:", WETH.balanceOf(bob) / 1e18, "WETH");
66+
}
67+
68+
function _setupTokenBalances() internal {
69+
// Give Alice and Bob some WETH
70+
vm.prank(WETH_WHALE);
71+
WETH.transfer(alice, 5 ether);
72+
vm.prank(WETH_WHALE);
73+
WETH.transfer(bob, 5 ether);
74+
75+
// Give Alice and Bob some additional VERSE for trading
76+
vm.prank(VERSE_WHALE);
77+
VERSE.transfer(alice, 1000e18);
78+
vm.prank(VERSE_WHALE);
79+
VERSE.transfer(bob, 1000e18);
80+
}
81+
82+
function testDiscountHookRealSwap() public {
83+
console.log("\n=== Testing DiscountHook_V3 Functionality ===");
84+
85+
// Test the hook directly to see if it can detect VERSE holders
86+
console.log("Alice VERSE balance:", VERSE.balanceOf(alice) / 1e18, "VERSE");
87+
console.log("Bob VERSE balance:", VERSE.balanceOf(bob) / 1e18, "VERSE");
88+
89+
// Try querying a swap instead of executing it
90+
console.log("\nTrying to query swap rates...");
91+
92+
try ROUTER.querySwapSingleTokenExactIn(
93+
POOL_ADDRESS,
94+
WETH,
95+
VERSE,
96+
1 ether,
97+
alice,
98+
""
99+
) returns (uint256 aliceAmountOut) {
100+
console.log("Alice query result:", aliceAmountOut / 1e18, "VERSE");
101+
102+
try ROUTER.querySwapSingleTokenExactIn(
103+
POOL_ADDRESS,
104+
WETH,
105+
VERSE,
106+
1 ether,
107+
bob,
108+
""
109+
) returns (uint256 bobAmountOut) {
110+
console.log("Bob query result:", bobAmountOut / 1e18, "VERSE");
111+
112+
if (aliceAmountOut > bobAmountOut) {
113+
console.log("SUCCESS: Alice gets more VERSE than Bob (discount working)");
114+
uint256 extraTokens = aliceAmountOut - bobAmountOut;
115+
console.log("Alice gets extra tokens:", extraTokens / 1e18, "VERSE");
116+
} else {
117+
console.log("NOTE: No difference detected or Bob gets more");
118+
}
119+
} catch {
120+
console.log("Failed to query swap for Bob");
121+
}
122+
} catch {
123+
console.log("Failed to query swap for Alice");
124+
}
125+
}
126+
127+
function _performSwap(address user, uint256 amountIn, string memory userLabel) internal returns (SwapResult memory) {
128+
console.log("\n--- Testing", userLabel, "---");
129+
130+
// Record balances before
131+
uint256 wethBefore = WETH.balanceOf(user);
132+
uint256 verseBefore = VERSE.balanceOf(user);
133+
134+
// Approve tokens
135+
vm.startPrank(user);
136+
WETH.approve(address(ROUTER), amountIn);
137+
138+
// Perform swap: WETH -> VERSE using the Router directly
139+
uint256 amountOut = ROUTER.swapSingleTokenExactIn(
140+
POOL_ADDRESS, // pool
141+
WETH, // tokenIn
142+
VERSE, // tokenOut
143+
amountIn, // exactAmountIn
144+
0, // minAmountOut (no slippage protection for test)
145+
block.timestamp + 1 hours, // deadline
146+
false, // wethIsEth
147+
"" // userData
148+
);
149+
150+
vm.stopPrank();
151+
152+
// Record balances after
153+
uint256 wethAfter = WETH.balanceOf(user);
154+
uint256 verseAfter = VERSE.balanceOf(user);
155+
156+
// Calculate actual amounts
157+
uint256 actualAmountIn = wethBefore - wethAfter;
158+
uint256 actualAmountOut = verseAfter - verseBefore;
159+
160+
console.log("Amount in (WETH):", actualAmountIn / 1e18);
161+
console.log("Amount out (VERSE):", actualAmountOut / 1e18);
162+
163+
// Calculate effective fee
164+
// For WETH/VERSE pool, we'll estimate based on actual swap results
165+
// Since both tokens have 18 decimals, we can compare directly
166+
uint256 expectedOutputWithoutFee = actualAmountIn; // Simplified for test - would need actual price data
167+
uint256 feeAmount = expectedOutputWithoutFee > actualAmountOut ? expectedOutputWithoutFee - actualAmountOut : 0;
168+
uint256 effectiveFeePercentage = expectedOutputWithoutFee > 0 ? (feeAmount * 1e18) / expectedOutputWithoutFee : 0;
169+
170+
console.log("Estimated fee amount (VERSE):", feeAmount / 1e18);
171+
console.log("Effective fee percentage:", effectiveFeePercentage / 1e14, "bps");
172+
173+
return SwapResult({
174+
amountIn: actualAmountIn,
175+
amountOut: actualAmountOut,
176+
swapFeeAmount: feeAmount,
177+
effectiveFeePercentage: effectiveFeePercentage
178+
});
179+
}
180+
181+
function testDiscountConfigEligibility() public {
182+
console.log("\n=== Testing DiscountConfig Eligibility ===");
183+
184+
// Test Alice (has VERSE)
185+
(bool success, bytes memory data) = DISCOUNT_CONFIG.staticcall(
186+
abi.encodeWithSignature("isEligible(address,address,uint256)", alice, address(VERSE), VERSE.balanceOf(alice))
187+
);
188+
189+
if (success && data.length > 0) {
190+
bool aliceEligible = abi.decode(data, (bool));
191+
console.log("Alice eligible for discount:", aliceEligible);
192+
assertTrue(aliceEligible, "Alice should be eligible");
193+
}
194+
195+
// Test Bob (no VERSE)
196+
(success, data) = DISCOUNT_CONFIG.staticcall(
197+
abi.encodeWithSignature("isEligible(address,address,uint256)", bob, address(VERSE), VERSE.balanceOf(bob))
198+
);
199+
200+
if (success && data.length > 0) {
201+
bool bobEligible = abi.decode(data, (bool));
202+
console.log("Bob eligible for discount:", bobEligible);
203+
assertFalse(bobEligible, "Bob should not be eligible");
204+
}
205+
}
206+
207+
function testPoolHookConfiguration() public {
208+
console.log("\n=== Testing Pool Hook Configuration ===");
209+
210+
// Check if pool has the hook configured
211+
(bool success, bytes memory data) = address(VAULT).staticcall(
212+
abi.encodeWithSignature("getHooksConfig(address)", POOL_ADDRESS)
213+
);
214+
215+
if (success && data.length > 0) {
216+
console.log("Pool hook configuration retrieved successfully");
217+
}
218+
219+
// Log pool details
220+
console.log("Pool address:", POOL_ADDRESS);
221+
console.log("Hook address:", DISCOUNT_HOOK);
222+
console.log("Config address:", DISCOUNT_CONFIG);
223+
}
224+
225+
function testVERSETokenInfo() public view {
226+
console.log("\n=== VERSE Token Information ===");
227+
console.log("VERSE Token Address:", address(VERSE));
228+
console.log("Alice VERSE Balance:", VERSE.balanceOf(alice) / 1e18, "VERSE");
229+
console.log("Bob VERSE Balance:", VERSE.balanceOf(bob) / 1e18, "VERSE");
230+
console.log("Total VERSE Supply:", VERSE.totalSupply() / 1e18, "VERSE");
231+
}
232+
}

0 commit comments

Comments
 (0)