Skip to content

Commit 458b2d5

Browse files
committed
Fork Test for USDC Jovay and Pharos
1 parent 6b815a3 commit 458b2d5

File tree

4 files changed

+184
-2
lines changed

4 files changed

+184
-2
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.24;
3+
4+
import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol";
5+
import {HybridLockReleaseUSDCTokenPool} from "../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol";
6+
import {RateLimiter} from "../../libraries/RateLimiter.sol";
7+
import {MCMSForkTest} from "./MCMSForkTest.t.sol";
8+
import {IERC20} from "@openzeppelin/contracts@4.8.3/token/ERC20/IERC20.sol";
9+
10+
contract HybridLockReleaseUSDCTokenPoolSetup is MCMSForkTest {
11+
address private s_poolAddress;
12+
address private s_jovayPoolAddress;
13+
address private s_pharosPoolAddress;
14+
address private s_tokenAddress;
15+
address private s_jovayTokenAddress;
16+
address private s_pharosTokenAddress;
17+
address private s_tokenAdminRegistryAddress;
18+
address private s_timelockAddress;
19+
bool private s_shouldUseLockRelease;
20+
uint64 private s_jovayChainSelector;
21+
uint64 private s_pharosChainSelector;
22+
uint256 private s_forkId;
23+
bytes[] private s_payloads;
24+
25+
function setUp() public {
26+
// Skip test if RPC_URL is not set (e.g., in CI without .env)
27+
string memory rpcUrl = vm.envOr("RPC_URL", string(""));
28+
vm.skip(bytes(rpcUrl).length == 0);
29+
30+
s_forkId = vm.createFork(rpcUrl);
31+
32+
// Load payloads dynamically based on PAYLOAD_COUNT
33+
uint256 payloadCount = vm.envUint("PAYLOAD_COUNT");
34+
s_payloads = new bytes[](payloadCount);
35+
for (uint256 i = 0; i < payloadCount; i++) {
36+
s_payloads[i] = vm.envBytes(string.concat("PAYLOAD_", vm.toString(i + 1)));
37+
}
38+
39+
s_jovayChainSelector = uint64(vm.envUint("JOVAY_CHAIN_SELECTOR"));
40+
s_pharosChainSelector = uint64(vm.envUint("PHAROS_CHAIN_SELECTOR"));
41+
s_poolAddress = vm.envAddress("POOL_ADDRESS");
42+
s_jovayPoolAddress = vm.envAddress("JOVAY_POOL_ADDRESS");
43+
s_pharosPoolAddress = vm.envAddress("PHAROS_POOL_ADDRESS");
44+
s_tokenAddress = vm.envAddress("TOKEN_ADDRESS");
45+
s_tokenAdminRegistryAddress = vm.envAddress("TOKEN_ADMIN_REGISTRY_ADDRESS");
46+
s_timelockAddress = vm.envAddress("TIMELOCK_ADDRESS");
47+
s_jovayTokenAddress = vm.envAddress("JOVAY_TOKEN_ADDRESS");
48+
s_pharosTokenAddress = vm.envAddress("PHAROS_TOKEN_ADDRESS");
49+
}
50+
51+
function testFork_Migration() public {
52+
vm.selectFork(s_forkId);
53+
54+
// Apply the payloads
55+
for (uint256 i = 0; i < s_payloads.length; i++) {
56+
_applyPayload(s_timelockAddress, s_payloads[i]);
57+
}
58+
59+
// Get the Liquidity Provider
60+
address liquidityProviderJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).getLiquidityProvider(s_jovayChainSelector);
61+
address liquidityProviderPharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).getLiquidityProvider(s_pharosChainSelector);
62+
63+
// Check the shouldUseLockRelease function
64+
bool shouldUseLockReleaseJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).shouldUseLockRelease(s_jovayChainSelector);
65+
bool shouldUseLockReleasePharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).shouldUseLockRelease(s_pharosChainSelector);
66+
67+
// Check the new supported chains
68+
bool isSupportedChainJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).isSupportedChain(s_jovayChainSelector);
69+
bool isSupportedChainPharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).isSupportedChain(s_pharosChainSelector);
70+
71+
// Check the new remote pools
72+
bytes[] memory remotePoolsJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).getRemotePools(s_jovayChainSelector);
73+
bytes[] memory remotePoolsPharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).getRemotePools(s_pharosChainSelector);
74+
75+
// Check the new remote token
76+
bytes memory remoteTokenJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).getRemoteToken(s_jovayChainSelector);
77+
bytes memory remoteTokenPharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).getRemoteToken(s_pharosChainSelector);
78+
79+
// Check the in and outbound rate limits
80+
RateLimiter.TokenBucket memory inboundRateLimitJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).getCurrentInboundRateLimiterState(s_jovayChainSelector);
81+
RateLimiter.TokenBucket memory outboundRateLimitJovay = HybridLockReleaseUSDCTokenPool(s_poolAddress).getCurrentOutboundRateLimiterState(s_jovayChainSelector);
82+
RateLimiter.TokenBucket memory inboundRateLimitPharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).getCurrentInboundRateLimiterState(s_pharosChainSelector);
83+
RateLimiter.TokenBucket memory outboundRateLimitPharos = HybridLockReleaseUSDCTokenPool(s_poolAddress).getCurrentOutboundRateLimiterState(s_pharosChainSelector);
84+
85+
// Ensure that the liquidiy provider matches the timelock address -- Jovay
86+
assertEq(
87+
liquidityProviderJovay,
88+
s_timelockAddress,
89+
"Liquidity provider should be set to the timelock address"
90+
);
91+
92+
// Ensure that the liquidiy provider matches the timelock address -- Pharos
93+
assertEq(
94+
liquidityProviderPharos,
95+
s_timelockAddress,
96+
"Liquidity provider should be set to the timelock address"
97+
);
98+
99+
// Ensure that the shouldUseLockRelease function matches the expected value -- Jovay
100+
assertEq(shouldUseLockReleaseJovay, true, "shouldUseLockRelease should be true");
101+
102+
// Ensure that the shouldUseLockRelease function matches the expected value -- Pharos
103+
assertEq(shouldUseLockReleasePharos, true, "shouldUseLockRelease should be true");
104+
105+
// Ensure that the isSupportedChain function matches the expected value -- Jovay
106+
assertEq(isSupportedChainJovay, true, "isSupportedChain should be true");
107+
108+
// Ensure that the isSupportedChain function matches the expected value -- Pharos
109+
assertEq(isSupportedChainPharos, true, "isSupportedChain should be true");
110+
111+
// Ensure that the remote pools array is not empty -- Jovay
112+
assertTrue(remotePoolsJovay.length > 0, "Remote pools array should not be empty for Jovay");
113+
assertEq(abi.decode(remotePoolsJovay[0], (address)), s_jovayPoolAddress, "First remote pool should be set to the pool address for Jovay");
114+
115+
// Ensure that the remote pools array is not empty -- Pharos
116+
assertTrue(remotePoolsPharos.length > 0, "Remote pools array should not be empty for Pharos");
117+
assertEq(abi.decode(remotePoolsPharos[0], (address)), s_pharosPoolAddress, "First remote pool should be set to the pool address for Pharos");
118+
119+
// Ensure that the remote token matches the expected value -- Jovay
120+
assertEq(abi.decode(remoteTokenJovay, (address)), s_jovayTokenAddress, "Remote token should be set to the token address");
121+
122+
// Ensure that the remote token matches the expected value -- Pharos
123+
assertEq(abi.decode(remoteTokenPharos, (address)), s_pharosTokenAddress, "Remote token should be set to the token address");
124+
125+
// Ensure that the inbound rate limit matches the expected value -- Jovay
126+
assertEq(inboundRateLimitJovay.capacity, 0, "Inbound rate limit should be 0");
127+
assertEq(inboundRateLimitJovay.rate, 0, "Inbound rate limit should be 0");
128+
129+
// Ensure that the outbound rate limit matches the expected value -- Jovay
130+
assertEq(outboundRateLimitJovay.capacity, 0, "Outbound rate limit should be 0");
131+
assertEq(outboundRateLimitJovay.rate, 0, "Outbound rate limit should be 0");
132+
133+
// Ensure that the inbound rate limit matches the expected value -- Pharos
134+
assertEq(inboundRateLimitPharos.capacity, 0, "Inbound rate limit should be 0");
135+
assertEq(inboundRateLimitPharos.rate, 0, "Inbound rate limit should be 0");
136+
137+
// Ensure that the outbound rate limit matches the expected value -- Pharos
138+
assertEq(outboundRateLimitPharos.capacity, 0, "Outbound rate limit should be 0");
139+
assertEq(outboundRateLimitPharos.rate, 0, "Outbound rate limit should be 0");
140+
141+
}
142+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.24;
3+
4+
import {Test} from "forge-std/Test.sol";
5+
6+
contract MCMSForkTest is Test {
7+
struct Call {
8+
address target;
9+
uint256 value;
10+
bytes data;
11+
}
12+
13+
error TransactionReverted();
14+
15+
function _applyPayload(address sender, bytes memory payload) internal {
16+
(MCMSForkTest.Call[] memory calls,,,) = abi.decode(payload, (MCMSForkTest.Call[], bytes32, bytes32, uint256));
17+
for (uint256 i = 0; i < calls.length; ++i) {
18+
MCMSForkTest.Call memory call = calls[i];
19+
vm.startPrank(sender);
20+
(bool success,) = call.target.call{value: call.value}(call.data);
21+
if (!success) revert TransactionReverted();
22+
vm.stopPrank();
23+
}
24+
}
25+
}

chains/evm/foundry.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ test = 'contracts'
77
out = 'foundry-artifacts'
88
cache_path = 'foundry-cache'
99
libs = ['node_modules']
10+
auto_detect_remappings = false
11+
12+
remappings = [
13+
'forge-std/=node_modules/@chainlink/contracts/src/v0.8/vendor/forge-std/src/',
14+
'@chainlink/contracts/=node_modules/@chainlink/contracts/',
15+
'@openzeppelin/contracts@4.7.3/=node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.7.3/contracts/',
16+
'@openzeppelin/contracts@4.8.3/=node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/',
17+
'@openzeppelin/contracts@4.9.6/=node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.9.6/contracts/',
18+
'@openzeppelin/contracts@5.0.2/=node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/',
19+
'@openzeppelin/contracts@5.1.0/=node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.1.0/contracts/',
20+
'@arbitrum/=node_modules/@arbitrum/',
21+
'@eth-optimism/=node_modules/@eth-optimism/',
22+
'@offchainlabs/=node_modules/@offchainlabs/',
23+
'@scroll-tech/=node_modules/@scroll-tech/',
24+
'@zksync/=node_modules/@zksync/',
25+
'solady/=node_modules/solady/',
26+
]
1027

1128
bytecode_hash = "none"
1229
ffi = false

chains/evm/remappings.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)