-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: XERC20 and XERC20 Lockbox integration tests (#3849)
- Loading branch information
Showing
13 changed files
with
485 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@hyperlane-xyz/core": patch | ||
--- | ||
|
||
fix: make XERC20 and XERC20 Lockbox proxy-able |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule forge-std
updated
38 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export ROUTER_ADDRESS=0xA34ceDf9068C5deE726C67A4e1DCfCc2D6E2A7fD | ||
export ERC20_ADDRESS=0x2416092f143378750bb29b79eD961ab195CcEea5 | ||
export XERC20_ADDRESS=0x2416092f143378750bb29b79eD961ab195CcEea5 | ||
export RPC_URL="https://rpc.blast.io" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export ROUTER_ADDRESS=0x8dfbEA2582F41c8C4Eb25252BbA392fd3c09449A | ||
export ADMIN_ADDRESS=0xa5B0D537CeBE97f087Dc5FE5732d70719caaEc1D | ||
export ERC20_ADDRESS=0xbf5495Efe5DB9ce00f80364C8B423567e58d2110 | ||
export XERC20_ADDRESS=0x2416092f143378750bb29b79eD961ab195CcEea5 | ||
export RPC_URL="https://eth.merkle.io" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity >=0.8.0; | ||
|
||
import "forge-std/Script.sol"; | ||
|
||
import {AnvilRPC} from "test/AnvilRPC.sol"; | ||
import {TypeCasts} from "contracts/libs/TypeCasts.sol"; | ||
|
||
import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; | ||
|
||
import {ProxyAdmin} from "contracts/upgrade/ProxyAdmin.sol"; | ||
|
||
import {HypXERC20Lockbox} from "contracts/token/extensions/HypXERC20Lockbox.sol"; | ||
import {IXERC20Lockbox} from "contracts/token/interfaces/IXERC20Lockbox.sol"; | ||
import {IXERC20} from "contracts/token/interfaces/IXERC20.sol"; | ||
import {IERC20} from "contracts/token/interfaces/IXERC20.sol"; | ||
|
||
// source .env.<CHAIN> | ||
// forge script ApproveLockbox.s.sol --broadcast --rpc-url localhost:XXXX | ||
contract ApproveLockbox is Script { | ||
address router = vm.envAddress("ROUTER_ADDRESS"); | ||
address admin = vm.envAddress("ADMIN_ADDRESS"); | ||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
|
||
ITransparentUpgradeableProxy proxy = ITransparentUpgradeableProxy(router); | ||
HypXERC20Lockbox old = HypXERC20Lockbox(router); | ||
address lockbox = address(old.lockbox()); | ||
address mailbox = address(old.mailbox()); | ||
ProxyAdmin proxyAdmin = ProxyAdmin(admin); | ||
|
||
function run() external { | ||
assert(proxyAdmin.getProxyAdmin(proxy) == admin); | ||
|
||
vm.startBroadcast(deployerPrivateKey); | ||
HypXERC20Lockbox logic = new HypXERC20Lockbox(lockbox, mailbox); | ||
proxyAdmin.upgradeAndCall( | ||
proxy, | ||
address(logic), | ||
abi.encodeCall(HypXERC20Lockbox.approveLockbox, ()) | ||
); | ||
vm.stopBroadcast(); | ||
|
||
vm.expectRevert("Initializable: contract is already initialized"); | ||
HypXERC20Lockbox(address(proxy)).initialize( | ||
address(0), | ||
address(0), | ||
mailbox | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity >=0.8.0; | ||
|
||
import "forge-std/Script.sol"; | ||
|
||
import {AnvilRPC} from "test/AnvilRPC.sol"; | ||
|
||
import {IXERC20Lockbox} from "contracts/token/interfaces/IXERC20Lockbox.sol"; | ||
import {IXERC20} from "contracts/token/interfaces/IXERC20.sol"; | ||
import {IERC20} from "contracts/token/interfaces/IXERC20.sol"; | ||
|
||
// source .env.<CHAIN> | ||
// anvil --fork-url $RPC_URL --port XXXX | ||
// forge script GrantLimits.s.sol --broadcast --unlocked --rpc-url localhost:XXXX | ||
contract GrantLimits is Script { | ||
address tester = 0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba; | ||
uint256 amount = 1 gwei; | ||
|
||
address router = vm.envAddress("ROUTER_ADDRESS"); | ||
IERC20 erc20 = IERC20(vm.envAddress("ERC20_ADDRESS")); | ||
IXERC20 xerc20 = IXERC20(vm.envAddress("XERC20_ADDRESS")); | ||
|
||
function runFrom(address account) internal { | ||
AnvilRPC.setBalance(account, 1 ether); | ||
AnvilRPC.impersonateAccount(account); | ||
vm.broadcast(account); | ||
} | ||
|
||
function run() external { | ||
address owner = xerc20.owner(); | ||
runFrom(owner); | ||
xerc20.setLimits(router, amount, amount); | ||
|
||
runFrom(address(erc20)); | ||
erc20.transfer(tester, amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
pragma solidity >=0.8.0; | ||
|
||
import "forge-std/Script.sol"; | ||
|
||
import {IXERC20Lockbox} from "../../contracts/token/interfaces/IXERC20Lockbox.sol"; | ||
import {IXERC20} from "../../contracts/token/interfaces/IXERC20.sol"; | ||
import {IERC20} from "../../contracts/token/interfaces/IXERC20.sol"; | ||
import {HypXERC20Lockbox} from "../../contracts/token/extensions/HypXERC20Lockbox.sol"; | ||
import {HypERC20Collateral} from "../../contracts/token/HypERC20Collateral.sol"; | ||
import {HypXERC20} from "../../contracts/token/extensions/HypXERC20.sol"; | ||
import {TransparentUpgradeableProxy} from "../../contracts/upgrade/TransparentUpgradeableProxy.sol"; | ||
import {ProxyAdmin} from "../../contracts/upgrade/ProxyAdmin.sol"; | ||
|
||
import {TypeCasts} from "../../contracts/libs/TypeCasts.sol"; | ||
import {TokenMessage} from "../../contracts/token/libs/TokenMessage.sol"; | ||
|
||
contract ezETH is Script { | ||
using TypeCasts for address; | ||
|
||
string ETHEREUM_RPC_URL = vm.envString("ETHEREUM_RPC_URL"); | ||
string BLAST_RPC_URL = vm.envString("BLAST_RPC_URL"); | ||
|
||
uint256 ethereumFork; | ||
uint32 ethereumDomainId = 1; | ||
address ethereumMailbox = 0xc005dc82818d67AF737725bD4bf75435d065D239; | ||
address ethereumLockbox = 0xC8140dA31E6bCa19b287cC35531c2212763C2059; | ||
|
||
uint256 blastFork; | ||
uint32 blastDomainId = 81457; | ||
address blastXERC20 = 0x2416092f143378750bb29b79eD961ab195CcEea5; | ||
address blastMailbox = 0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7; | ||
|
||
uint256 amount = 100; | ||
|
||
function setUp() public { | ||
ethereumFork = vm.createFork(ETHEREUM_RPC_URL); | ||
blastFork = vm.createFork(BLAST_RPC_URL); | ||
} | ||
|
||
function run() external { | ||
address deployer = address(this); | ||
bytes32 recipient = deployer.addressToBytes32(); | ||
bytes memory tokenMessage = TokenMessage.format(recipient, amount, ""); | ||
vm.selectFork(ethereumFork); | ||
HypXERC20Lockbox hypXERC20Lockbox = new HypXERC20Lockbox( | ||
ethereumLockbox, | ||
ethereumMailbox | ||
); | ||
ProxyAdmin ethAdmin = new ProxyAdmin(); | ||
TransparentUpgradeableProxy ethProxy = new TransparentUpgradeableProxy( | ||
address(hypXERC20Lockbox), | ||
address(ethAdmin), | ||
abi.encodeCall( | ||
HypXERC20Lockbox.initialize, | ||
(address(0), address(0), deployer) | ||
) | ||
); | ||
hypXERC20Lockbox = HypXERC20Lockbox(address(ethProxy)); | ||
|
||
vm.selectFork(blastFork); | ||
HypXERC20 hypXERC20 = new HypXERC20(blastXERC20, blastMailbox); | ||
ProxyAdmin blastAdmin = new ProxyAdmin(); | ||
TransparentUpgradeableProxy blastProxy = new TransparentUpgradeableProxy( | ||
address(hypXERC20), | ||
address(blastAdmin), | ||
abi.encodeCall( | ||
HypERC20Collateral.initialize, | ||
(address(0), address(0), deployer) | ||
) | ||
); | ||
hypXERC20 = HypXERC20(address(blastProxy)); | ||
hypXERC20.enrollRemoteRouter( | ||
ethereumDomainId, | ||
address(hypXERC20Lockbox).addressToBytes32() | ||
); | ||
|
||
// grant `amount` mint and burn limit to warp route | ||
vm.prank(IXERC20(blastXERC20).owner()); | ||
IXERC20(blastXERC20).setLimits(address(hypXERC20), amount, amount); | ||
|
||
// test sending `amount` on warp route | ||
vm.prank(0x7BE481D464CAD7ad99500CE8A637599eB8d0FCDB); // ezETH whale | ||
IXERC20(blastXERC20).transfer(address(this), amount); | ||
IXERC20(blastXERC20).approve(address(hypXERC20), amount); | ||
uint256 value = hypXERC20.quoteGasPayment(ethereumDomainId); | ||
hypXERC20.transferRemote{value: value}( | ||
ethereumDomainId, | ||
recipient, | ||
amount | ||
); | ||
|
||
// test receiving `amount` on warp route | ||
vm.prank(blastMailbox); | ||
hypXERC20.handle( | ||
ethereumDomainId, | ||
address(hypXERC20Lockbox).addressToBytes32(), | ||
tokenMessage | ||
); | ||
|
||
vm.selectFork(ethereumFork); | ||
hypXERC20Lockbox.enrollRemoteRouter( | ||
blastDomainId, | ||
address(hypXERC20).addressToBytes32() | ||
); | ||
|
||
// grant `amount` mint and burn limit to warp route | ||
IXERC20 ethereumXERC20 = hypXERC20Lockbox.xERC20(); | ||
vm.prank(ethereumXERC20.owner()); | ||
ethereumXERC20.setLimits(address(hypXERC20Lockbox), amount, amount); | ||
|
||
// test sending `amount` on warp route | ||
IERC20 erc20 = IXERC20Lockbox(ethereumLockbox).ERC20(); | ||
vm.prank(ethereumLockbox); | ||
erc20.transfer(address(this), amount); | ||
erc20.approve(address(hypXERC20Lockbox), amount); | ||
hypXERC20Lockbox.transferRemote(blastDomainId, recipient, amount); | ||
|
||
// test receiving `amount` on warp route | ||
vm.prank(ethereumMailbox); | ||
hypXERC20Lockbox.handle( | ||
blastDomainId, | ||
address(hypXERC20).addressToBytes32(), | ||
tokenMessage | ||
); | ||
} | ||
} |
Oops, something went wrong.