WormholeTestUtils.t.sol 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // SPDX-License-Identifier: Apache 2
  2. pragma solidity ^0.8.0;
  3. import "../../contracts/wormhole/Implementation.sol";
  4. import "../../contracts/wormhole/Setup.sol";
  5. import "../../contracts/wormhole/Wormhole.sol";
  6. import "../../contracts/wormhole/interfaces/IWormhole.sol";
  7. import "forge-std/Test.sol";
  8. abstract contract WormholeTestUtils is Test {
  9. function setUpWormhole(uint8 numGuardians) public returns (address) {
  10. Implementation wormholeImpl = new Implementation();
  11. Setup wormholeSetup = new Setup();
  12. Wormhole wormhole = new Wormhole(address(wormholeSetup), new bytes(0));
  13. address[] memory initSigners = new address[](numGuardians);
  14. for (uint256 i = 0; i < numGuardians; ++i) {
  15. initSigners[i] = vm.addr(i + 1); // i+1 is the private key for the i-th signer.
  16. }
  17. // These values are the default values used in our tilt test environment
  18. // and are not important.
  19. Setup(address(wormhole)).setup(
  20. address(wormholeImpl),
  21. initSigners,
  22. 2, // Ethereum chain ID
  23. 1, // Governance source chain ID (1 = solana)
  24. 0x0000000000000000000000000000000000000000000000000000000000000004 // Governance source address
  25. );
  26. return address(wormhole);
  27. }
  28. function generateVaa(
  29. uint32 timestamp,
  30. uint16 emitterChainId,
  31. bytes32 emitterAddress,
  32. uint64 sequence,
  33. bytes memory payload,
  34. uint8 numSigners
  35. ) public returns (bytes memory vaa) {
  36. bytes memory body = abi.encodePacked(
  37. timestamp,
  38. uint32(0), // Nonce. It is zero for single VAAs.
  39. emitterChainId,
  40. emitterAddress,
  41. sequence,
  42. uint8(0), // Consistency level (sometimes no. confirmation block). Not important here.
  43. payload
  44. );
  45. bytes32 hash = keccak256(abi.encodePacked(keccak256(body)));
  46. bytes memory signatures = new bytes(0);
  47. for (uint256 i = 0; i < numSigners; ++i) {
  48. (uint8 v, bytes32 r, bytes32 s) = vm.sign(i + 1, hash);
  49. // encodePacked uses padding for arrays and we don't want it, so we manually concat them.
  50. signatures = abi.encodePacked(
  51. signatures,
  52. uint8(i), // Guardian index of the signature
  53. r,
  54. s,
  55. v - 27 // v is either 27 or 28. 27 is added to v in Eth (following BTC) but Wormhole doesn't use it.
  56. );
  57. }
  58. vaa = abi.encodePacked(
  59. uint8(1), // Version
  60. uint32(0), // Guardian set index. it is initialized by 0
  61. numSigners,
  62. signatures,
  63. body
  64. );
  65. }
  66. }
  67. contract WormholeTestUtilsTest is Test, WormholeTestUtils {
  68. function testGenerateVaaWorks() public {
  69. IWormhole wormhole = IWormhole(setUpWormhole(5));
  70. bytes memory vaa = generateVaa(
  71. 112,
  72. 7,
  73. 0x0000000000000000000000000000000000000000000000000000000000000bad,
  74. 10,
  75. hex"deadbeaf",
  76. 4
  77. );
  78. (Structs.VM memory vm, bool valid, ) = wormhole.parseAndVerifyVM(vaa);
  79. assertTrue(valid);
  80. assertEq(vm.timestamp, 112);
  81. assertEq(vm.emitterChainId, 7);
  82. assertEq(vm.emitterAddress, 0x0000000000000000000000000000000000000000000000000000000000000bad);
  83. assertEq(vm.payload, hex"deadbeaf");
  84. assertEq(vm.signatures.length, 4);
  85. }
  86. }