pragma solidity 0.8.20; import {Test} from "forge-std/Test.sol"; import {Gatekeeper} from "../../src/Gatekeeper.sol"; contract GatekeeperTest is Test { address constant ALICE = 0x0000000000000000000000000000000000000001; address constant BOB = 0x0000000000000000000000000000000000000002; uint256 constant EXISTENTIAL = 1337; uint256 constant INIT_AMOUNT = 69 * 1e18; Gatekeeper gatekeeper; event Ghosted(bytes32 indexed receiver, uint256 indexed amount); function setUp() public { vm.prank(ALICE, ALICE); gatekeeper = new Gatekeeper(EXISTENTIAL, address(0)); } function test_correctInitialization() public { assertEq(gatekeeper.staking(), ALICE); assertEq(gatekeeper.ghostedSupply(), 0); bytes32 receiver = bytes32(abi.encodePacked(ALICE)); vm.prank(ALICE); gatekeeper.ghost(receiver, INIT_AMOUNT); vm.prank(BOB); Gatekeeper anotherGatekeeper = new Gatekeeper(EXISTENTIAL, address(gatekeeper)); assertEq(anotherGatekeeper.staking(), ALICE); assertEq(anotherGatekeeper.ghostedSupply(), INIT_AMOUNT); assertEq(anotherGatekeeper.existentialDeposit(), EXISTENTIAL); } function test_ghostTokensWork(uint256 ghostAmount) public { vm.assume(ghostAmount >= EXISTENTIAL && ghostAmount < type(uint96).max); bytes32 receiver = bytes32(abi.encodePacked(ALICE)); uint256 ghostedSupply = gatekeeper.ghostedSupply(); vm.prank(ALICE); gatekeeper.ghost(receiver, ghostAmount); assertEq(gatekeeper.ghostedSupply(), ghostedSupply + ghostAmount); } function test_couldNotGhostTokensFromArbitraryAddress(address someone) public { vm.assume(someone != ALICE); bytes32 receiver = bytes32(abi.encodePacked(ALICE)); vm.expectRevert(); vm.prank(someone); gatekeeper.ghost(receiver, 69); assertEq(gatekeeper.ghostedSupply(), 0); } function test_ghostTokensEmitsEvent(uint256 ghostAmount) public { vm.assume(ghostAmount >= EXISTENTIAL); bytes32 receiver = bytes32(abi.encodePacked(ALICE)); vm.expectEmit(true, true, true, false, address(gatekeeper)); emit Ghosted(receiver, ghostAmount); vm.prank(ALICE); gatekeeper.ghost(receiver, ghostAmount); } // TODO: revisit with actual signatures from the cargo test // function test_materializeWork(uint256 ghostAmount) public { // vm.prank(ALICE); // gatekeeper.materialize(0, ghostAmount, 0, ALICE); // } function test_rotateWork(bytes32 aggregatedPublicKey) public { vm.warp(block.timestamp + 1); vm.prank(address(gatekeeper)); gatekeeper.rotate(block.timestamp, aggregatedPublicKey, 0); } function test_couldNotBridgeBelowExistential(uint256 amount) public { vm.assume(amount < EXISTENTIAL); bytes32 receiver = bytes32(abi.encodePacked(ALICE)); vm.expectRevert(); vm.prank(ALICE); gatekeeper.ghost(receiver, amount); assertEq(gatekeeper.ghostedSupply(), 0); } function test_signatureVerificationsWorks() public { assertEq(gatekeeper.deployer(), ALICE); vm.prank(ALICE); gatekeeper.updatePublicKeyMetadata(0, 0x875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e4669, 0); (bytes32 prevPublicKey, uint8 prevParity, uint64 prevSession) = gatekeeper.latestPublicKeyInfo(); gatekeeper.verify( hex"49f03a670000000000000000000000000000000000000000000000000000000000000000875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e46690000000000000000000000000000000000000000000000000000000000000000", hex"044d9fa18df9da04381ed256981570a6ef6a0893496ded966fc994662df931ed423b29e2737394b31d8498594caad7b77e36ab31ac79df3796a1b6f26baa5552ae", 0x24029a571fcaeadd14f4afe8be62afe3d07876ae270c3caf446ecb6cfc7c08f2 ); (bytes32 publicKey, uint8 parity, uint64 session) = gatekeeper.latestPublicKeyInfo(); assertEq(publicKey, prevPublicKey); assertEq(parity, prevParity); assertEq(session, prevSession); vm.expectRevert(); gatekeeper.verify( hex"49f03a6700000000000000000000000000000000000000000000000000000000000000023492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000", hex"042b45a8909a137e7bab5caf4b2870ece0469c6a4149c10074cfdaf2c114a65daefe14179830c95d07fea439ce78d2ad11898578e5e678dbcb98a7576da9e57c77", 0x5a61b59cededac4010b89bc6935e0cb7d975f5e2db457227ee473203de5247ed ); gatekeeper.verify( hex"49f03a6700000000000000000000000000000000000000000000000000000000000000014e8c1fe96d6737cdabbcc96501d6656b9d0b659b3a528ef507f2d52bef29e1570000000000000000000000000000000000000000000000000000000000000000", hex"04d4c4daeb68bf8e40db4b516ddf3be9dd0f56a81809945e30bf06b7e5b26d1b27c83367de842f00c915f06ab1755dc511a3a3fe213308b5e65c6832d9d9bb3b38", 0xd93d1b1613277ddb27df66bdea16d7b91adf975eb150e27a872ce035655ec13d ); (publicKey, parity, session) = gatekeeper.latestPublicKeyInfo(); assert(publicKey != prevPublicKey); assertEq(parity, prevParity); assertEq(session, prevSession + 1); prevPublicKey = publicKey; prevParity = parity; prevSession = session; gatekeeper.verify( hex"49f03a6700000000000000000000000000000000000000000000000000000000000000023492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000", hex"042b45a8909a137e7bab5caf4b2870ece0469c6a4149c10074cfdaf2c114a65daefe14179830c95d07fea439ce78d2ad11898578e5e678dbcb98a7576da9e57c77", 0x5a61b59cededac4010b89bc6935e0cb7d975f5e2db457227ee473203de5247ed ); (publicKey, parity, session) = gatekeeper.latestPublicKeyInfo(); assert(publicKey != prevPublicKey); assertEq(parity, prevParity); assertEq(session, prevSession + 1); vm.expectRevert(); gatekeeper.verify( hex"49f03a670000000000000000000000000000000000000000000000000000000000000000875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e46690000000000000000000000000000000000000000000000000000000000000000", hex"044d9fa18df9da04381ed256981570a6ef6a0893496ded966fc994662df931ed423b29e2737394b31d8498594caad7b77e36ab31ac79df3796a1b6f26baa5552ae", 0x24029a571fcaeadd14f4afe8be62afe3d07876ae270c3caf446ecb6cfc7c08f2 ); vm.expectRevert(); gatekeeper.verify( hex"49f03a6700000000000000000000000000000000000000000000000000000000000000014e8c1fe96d6737cdabbcc96501d6656b9d0b659b3a528ef507f2d52bef29e1570000000000000000000000000000000000000000000000000000000000000000", hex"04d4c4daeb68bf8e40db4b516ddf3be9dd0f56a81809945e30bf06b7e5b26d1b27c83367de842f00c915f06ab1755dc511a3a3fe213308b5e65c6832d9d9bb3b38", 0xd93d1b1613277ddb27df66bdea16d7b91adf975eb150e27a872ce035655ec13d ); vm.expectRevert(); gatekeeper.verify( hex"49f03a6700000000000000000000000000000000000000000000000000000000000000023492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000", hex"042b45a8909a137e7bab5caf4b2870ece0469c6a4149c10074cfdaf2c114a65daefe14179830c95d07fea439ce78d2ad11898578e5e678dbcb98a7576da9e57c77", 0x5a61b59cededac4010b89bc6935e0cb7d975f5e2db457227ee473203de5247ed ); } }