emit event during the weaver insertion
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
635853f170
commit
b1e9be968e
@ -109,14 +109,12 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
||||
return (publicKey, state.parity, state.session);
|
||||
}
|
||||
|
||||
function ghost(bytes32 receiver, uint256 amount) external override returns (uint256) {
|
||||
function ghost(bytes32 receiver, uint256 amount) external override {
|
||||
if (msg.sender != staking) revert NotStaking();
|
||||
if (amount < EXISTENTIAL_DEPOSIT) revert NonExistentAmount();
|
||||
|
||||
IStorageHistory(storageHistory).increaseBridgeIn(amount);
|
||||
|
||||
emit Ghosted(receiver, amount);
|
||||
return _insertTreeNode(receiver, amount);
|
||||
_insertTreeNode(receiver, amount);
|
||||
}
|
||||
|
||||
function verify(
|
||||
|
||||
@ -14,7 +14,6 @@ interface IGatekeeper {
|
||||
error InsufficientValue();
|
||||
error ExecutionReverted();
|
||||
|
||||
event Ghosted(bytes32 indexed receiver, uint256 indexed amount);
|
||||
event Recalled(address indexed receiver, uint256 indexed amount);
|
||||
event Rotated(bytes32 indexed aggregatedPublicKey, uint8 indexed parity);
|
||||
event VoluntaryVerification(address indexed sender, uint256 indexed gasSpent);
|
||||
@ -29,6 +28,6 @@ interface IGatekeeper {
|
||||
function govern(uint256 session, uint256 payload, bytes calldata call) external returns (bytes calldata);
|
||||
function recall(uint256 session, uint256 amount, uint256 payload) external;
|
||||
function rotate(uint256 session, bytes32 publicKey, uint8 parity) external;
|
||||
function ghost(bytes32 receiver, uint256 amount) external returns (uint256);
|
||||
function ghost(bytes32 receiver, uint256 amount) external;
|
||||
function initialize(address previousAddress) external;
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
interface IWeaver {
|
||||
event ThreadInserted(uint256 index, uint256 session);
|
||||
|
||||
function currentWeavingSession() external view returns (uint256);
|
||||
function startWeavingSession() external view returns (uint256);
|
||||
function getSlotValues(uint256 globalIndex, uint256 session, uint256 atBlock) external view returns (bytes32[] memory);
|
||||
|
||||
@ -14,8 +14,8 @@ contract WeaverMock is Weaver {
|
||||
return _previousAddress;
|
||||
}
|
||||
|
||||
function insertTreeNode(bytes32 receiver, uint256 amount) external returns (uint256) {
|
||||
return _insertTreeNode(receiver, amount);
|
||||
function insertTreeNode(bytes32 receiver, uint256 amount) external {
|
||||
_insertTreeNode(receiver, amount);
|
||||
}
|
||||
|
||||
function computeArgumentsHash(
|
||||
|
||||
@ -134,9 +134,10 @@ abstract contract Weaver is IWeaver {
|
||||
return proof;
|
||||
}
|
||||
|
||||
function _insertTreeNode(bytes32 who, uint256 amount) internal returns (uint256 globalIndex) {
|
||||
function _insertTreeNode(bytes32 who, uint256 amount) internal {
|
||||
uint256 session = currentWeavingSession;
|
||||
globalIndex = _filledEntries[session];
|
||||
uint256 globalIndex = _filledEntries[session];
|
||||
|
||||
if (globalIndex >= ENTRIES) {
|
||||
unchecked { ++session; }
|
||||
currentWeavingSession = session;
|
||||
@ -158,6 +159,8 @@ abstract contract Weaver is IWeaver {
|
||||
_slotValues[session][slotIndex].push(preimage);
|
||||
|
||||
unchecked { ++_filledEntries[session]; }
|
||||
|
||||
emit ThreadInserted(globalIndex, session);
|
||||
}
|
||||
|
||||
function _computeArgumentsHash(uint256 i, uint256 a, bytes32 r) internal pure returns (bytes32) {
|
||||
|
||||
@ -203,7 +203,7 @@ contract GatekeeperTest is Test {
|
||||
Gatekeeper gatekeeper;
|
||||
MockStaking staking;
|
||||
|
||||
event Ghosted(bytes32 indexed receiver, uint256 indexed amount);
|
||||
event ThreadInserted(uint256 index, uint256 session);
|
||||
|
||||
function setUp() public {
|
||||
vm.prank(ALICE, ALICE);
|
||||
@ -247,7 +247,7 @@ contract GatekeeperTest is Test {
|
||||
bytes32 receiver = bytes32(abi.encodePacked(ALICE));
|
||||
|
||||
vm.expectEmit(true, true, true, false, address(gatekeeper));
|
||||
emit Ghosted(receiver, ghostAmount);
|
||||
emit ThreadInserted(0, 0);
|
||||
vm.prank(ALICE);
|
||||
staking.runGhost(receiver, ghostAmount);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
pragma solidity 0.8.20;
|
||||
|
||||
import {Test} from "forge-std/Test.sol";
|
||||
import {Test, Vm} from "forge-std/Test.sol";
|
||||
|
||||
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
||||
import {Hashes} from "../../src/libraries/Hashes.sol";
|
||||
@ -21,9 +21,9 @@ contract MockStaking {
|
||||
governor = msg.sender;
|
||||
}
|
||||
|
||||
function ghost(bytes32 receiver, uint256 amount) external returns (uint256) {
|
||||
function ghost(bytes32 receiver, uint256 amount) external {
|
||||
require(msg.sender == governor);
|
||||
return gatekeeper.ghost(receiver, amount);
|
||||
gatekeeper.ghost(receiver, amount);
|
||||
}
|
||||
|
||||
function createNewGatekeeper() external {
|
||||
@ -127,25 +127,25 @@ contract GatekeeperWeaverTest is Test {
|
||||
}
|
||||
|
||||
function test_insertationWorksAsExpected() public {
|
||||
uint256 currentWeavingSession = gatekeeper.currentWeavingSession();
|
||||
uint256 maxCount = gatekeeper.ENTRIES();
|
||||
uint256 currentWeavingSession;
|
||||
uint256 newWeavingSession;
|
||||
uint256 globalIndex;
|
||||
|
||||
(bytes32[] memory whos, uint256[] memory amounts) = _prepareArrays(maxCount);
|
||||
vm.recordLogs();
|
||||
|
||||
for (uint256 i = 0; i < maxCount; i++) {
|
||||
if (i % 5 == 0) { vm.roll(block.number + 1); }
|
||||
globalIndex = _insertWithAssert(currentWeavingSession, amounts[i], whos[i]);
|
||||
(globalIndex, currentWeavingSession) = _insertWithAssert(amounts[i], whos[i]);
|
||||
assertTrue(_verifyProof(globalIndex, currentWeavingSession, block.number, amounts[i], whos[i]));
|
||||
}
|
||||
|
||||
globalIndex = _insertWithAssert(currentWeavingSession, amounts[69], whos[69]);
|
||||
uint256 newSession = gatekeeper.currentWeavingSession();
|
||||
|
||||
assertEq(currentWeavingSession + 1, newSession);
|
||||
(globalIndex, newWeavingSession) = _insertWithAssert(amounts[69], whos[69]);
|
||||
assertEq(currentWeavingSession + 1, newWeavingSession);
|
||||
vm.roll(block.number + 1337);
|
||||
|
||||
assertTrue(_verifyProof(globalIndex, newSession, block.number, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(globalIndex, newWeavingSession, block.number, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(0, currentWeavingSession, block.number, amounts[0], whos[0]));
|
||||
assertTrue(_verifyProof(69, currentWeavingSession, block.number, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(420, currentWeavingSession, block.number, amounts[420], whos[420]));
|
||||
@ -156,7 +156,7 @@ contract GatekeeperWeaverTest is Test {
|
||||
assertTrue(_verifyProof(69, currentWeavingSession, 100, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(420, currentWeavingSession, 100, amounts[420], whos[420]));
|
||||
|
||||
assertFalse(_verifyProof(globalIndex, newSession, 100, amounts[69], whos[69]));
|
||||
assertFalse(_verifyProof(globalIndex, newWeavingSession, 100, amounts[69], whos[69]));
|
||||
assertFalse(_verifyProof(1337, currentWeavingSession, 100, amounts[1337], whos[1337]));
|
||||
assertFalse(_verifyProof(2047, currentWeavingSession, 100, amounts[2047], whos[2047]));
|
||||
|
||||
@ -174,7 +174,7 @@ contract GatekeeperWeaverTest is Test {
|
||||
staking.ghost(whos[i], amounts[i]);
|
||||
}
|
||||
|
||||
assertTrue(_verifyProof(globalIndex, newSession, block.number, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(globalIndex, newWeavingSession, block.number, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(0, currentWeavingSession, block.number, amounts[0], whos[0]));
|
||||
assertTrue(_verifyProof(69, currentWeavingSession, block.number, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(420, currentWeavingSession, block.number, amounts[420], whos[420]));
|
||||
@ -185,7 +185,7 @@ contract GatekeeperWeaverTest is Test {
|
||||
assertTrue(_verifyProof(69, currentWeavingSession, 100, amounts[69], whos[69]));
|
||||
assertTrue(_verifyProof(420, currentWeavingSession, 100, amounts[420], whos[420]));
|
||||
|
||||
assertFalse(_verifyProof(globalIndex, newSession, 100, amounts[69], whos[69]));
|
||||
assertFalse(_verifyProof(globalIndex, newWeavingSession, 100, amounts[69], whos[69]));
|
||||
assertFalse(_verifyProof(1337, currentWeavingSession, 100, amounts[1337], whos[1337]));
|
||||
assertFalse(_verifyProof(2047, currentWeavingSession, 100, amounts[2047], whos[2047]));
|
||||
|
||||
@ -212,41 +212,43 @@ contract GatekeeperWeaverTest is Test {
|
||||
}
|
||||
|
||||
function _insertWithAssert(
|
||||
uint256 session,
|
||||
uint256 amount,
|
||||
bytes32 who
|
||||
) private returns (uint256 globalIndex) {
|
||||
uint256 targetSlot = gatekeeper.filledEntries(session);
|
||||
bytes32 previousHash = gatekeeper.treeNodesLatest(session, targetSlot);
|
||||
uint256 prevEntries = gatekeeper.filledEntries(session);
|
||||
uint160 prevLength = gatekeeper.slotLengths(session, targetSlot);
|
||||
) private returns (uint256 globalIndex, uint256 emittedSession) {
|
||||
uint256 preSession = gatekeeper.currentWeavingSession();
|
||||
|
||||
uint256 targetSlot = gatekeeper.filledEntries(preSession);
|
||||
bytes32 previousHash = gatekeeper.treeNodesLatest(preSession, targetSlot);
|
||||
uint256 prevEntries = gatekeeper.filledEntries(preSession);
|
||||
uint160 prevLength = gatekeeper.slotLengths(preSession, targetSlot);
|
||||
|
||||
vm.prank(ALICE);
|
||||
globalIndex = staking.ghost(who, amount);
|
||||
staking.ghost(who, amount);
|
||||
(globalIndex, emittedSession) = _getInsertedDataFromLogs();
|
||||
|
||||
if (preSession != emittedSession) {
|
||||
assertEq(preSession + 1, emittedSession);
|
||||
assertEq(emittedSession, gatekeeper.currentWeavingSession());
|
||||
|
||||
if (session + 1 == gatekeeper.currentWeavingSession()) {
|
||||
assertEq(prevLength, gatekeeper.DEPTH());
|
||||
assertEq(gatekeeper.slotLengths(session + 1, 0), 1);
|
||||
assertEq(gatekeeper.slotLengths(emittedSession, 0), 1);
|
||||
assertEq(prevEntries, gatekeeper.ENTRIES());
|
||||
assertEq(gatekeeper.filledEntries(session + 1), 1);
|
||||
assertEq(session + 1, gatekeeper.currentWeavingSession());
|
||||
assertEq(gatekeeper.filledEntries(emittedSession), 1);
|
||||
|
||||
session += 1;
|
||||
previousHash = bytes32(0);
|
||||
prevLength = gatekeeper.slotLengths(session, 0);
|
||||
} else {
|
||||
assertEq(prevLength + 1, gatekeeper.slotLengths(session, targetSlot));
|
||||
assertEq(prevEntries + 1, gatekeeper.filledEntries(session));
|
||||
assertEq(prevLength + 1, gatekeeper.slotLengths(emittedSession, targetSlot));
|
||||
assertEq(prevEntries + 1, gatekeeper.filledEntries(emittedSession));
|
||||
}
|
||||
|
||||
{
|
||||
bytes32 preimage1 = gatekeeper.slotValues(session, globalIndex);
|
||||
bytes32 preimage1 = gatekeeper.slotValues(emittedSession, globalIndex);
|
||||
bytes32 preimage2 = gatekeeper.computePreimage(globalIndex, amount, who);
|
||||
assertEq(preimage1, preimage2);
|
||||
}
|
||||
|
||||
{
|
||||
bytes32 nodeHash1 = gatekeeper.treeNodesLatest(session, globalIndex);
|
||||
bytes32 nodeHash1 = gatekeeper.treeNodesLatest(emittedSession, globalIndex);
|
||||
bytes32 preimageHash = Hashes.efficientKeccak256(
|
||||
gatekeeper.computePreimage(globalIndex, amount, who)
|
||||
);
|
||||
@ -268,4 +270,17 @@ contract GatekeeperWeaverTest is Test {
|
||||
|
||||
return (whos, amounts);
|
||||
}
|
||||
|
||||
function _getInsertedDataFromLogs() private returns (uint256 index, uint256 session) {
|
||||
Vm.Log[] memory entries = vm.getRecordedLogs();
|
||||
bytes32 targetTopic = keccak256("ThreadInserted(uint256,uint256)");
|
||||
|
||||
for (uint256 i = entries.length; i > 0; i--) {
|
||||
if (entries[i - 1].topics.length > 0 && entries[i - 1].topics[0] == targetTopic) {
|
||||
(index, session) = abi.decode(entries[i - 1].data, (uint256, uint256));
|
||||
return (index, session);
|
||||
}
|
||||
}
|
||||
revert("Target event not found in logs");
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +86,6 @@ contract StakingTest is Test {
|
||||
|
||||
event DistributorSet(address distributor);
|
||||
event WarmupSet(uint256 warmup);
|
||||
event Ghosted(bytes32 indexed receiver, uint256 indexed amount);
|
||||
|
||||
function setUp() public {
|
||||
vm.startPrank(INITIALIZER);
|
||||
@ -640,23 +639,6 @@ contract StakingTest is Test {
|
||||
assertEq(ghst.totalSupply(), 0);
|
||||
}
|
||||
|
||||
function test_ghostTokensEmitsEvent() public {
|
||||
_prepareAndRoll(ALICE, BIG_AMOUNT, true, true);
|
||||
uint256 aliceBalance = stnk.balanceOf(ALICE);
|
||||
|
||||
vm.startPrank(ALICE);
|
||||
stnk.approve(address(staking), aliceBalance);
|
||||
uint256 ghstBalance = staking.wrap(ALICE, aliceBalance);
|
||||
vm.stopPrank();
|
||||
|
||||
bytes32 receiver = bytes32(abi.encodePacked(ALICE));
|
||||
vm.expectEmit(true, true, true, false, staking.gatekeeper());
|
||||
emit Ghosted(receiver, ghstBalance);
|
||||
|
||||
vm.prank(ALICE);
|
||||
staking.ghost(receiver, ghstBalance);
|
||||
}
|
||||
|
||||
function test_breakoutLogicWorks() public {
|
||||
uint256 initialIndex = staking.index();
|
||||
bytes32 receiver = bytes32(abi.encodePacked(ALICE));
|
||||
@ -678,9 +660,6 @@ contract StakingTest is Test {
|
||||
uint256 range = (payout * 3) / 100;
|
||||
requestedPayout = (pseudoRandom % range) + 1;
|
||||
|
||||
vm.expectEmit(true, true, true, false, staking.gatekeeper());
|
||||
emit Ghosted(receiver, requestedPayout);
|
||||
|
||||
vm.prank(ALICE);
|
||||
staking.breakout(receiver, requestedPayout);
|
||||
expectedPayout += requestedPayout;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user