130 lines
5.1 KiB
Solidity
130 lines
5.1 KiB
Solidity
pragma solidity 0.8.20;
|
|
|
|
import {Test} from "forge-std/Test.sol";
|
|
|
|
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
|
import {IStorageHistory} from "../../src/interfaces/IStorageHistory.sol";
|
|
import {RequestPacking} from "../../src/libraries/Packing.sol";
|
|
|
|
contract MockStaking is Test {
|
|
Gatekeeper public gatekeeper;
|
|
|
|
mapping(address => uint256) private _materializedAmounts;
|
|
|
|
constructor(uint256 existential) {
|
|
gatekeeper = new Gatekeeper(existential, address(0));
|
|
}
|
|
|
|
function redoGatekeeper(uint256 existential) external {
|
|
gatekeeper = new Gatekeeper(existential, address(gatekeeper));
|
|
}
|
|
|
|
function runGhost(bytes32 receiver, uint256 amount) external {
|
|
gatekeeper.ghost(receiver, amount);
|
|
}
|
|
|
|
function runMaterialize(uint256 exodusSession, uint256 amount, uint256 packed) external {
|
|
vm.prank(address(gatekeeper));
|
|
gatekeeper.materialize(exodusSession, amount, packed);
|
|
}
|
|
|
|
function materialize(address receiver, uint256 amount) external {
|
|
_materializedAmounts[receiver] += amount;
|
|
}
|
|
|
|
function materializedAmount(address who) external view returns (uint256) {
|
|
return _materializedAmounts[who];
|
|
}
|
|
}
|
|
|
|
contract GatekeeperStorageHistoryTest is Test {
|
|
using RequestPacking for RequestPacking.RequestPayload;
|
|
|
|
address constant ALICE = 0x0000000000000000000000000000000000000001;
|
|
address constant BOB = 0x0000000000000000000000000000000000000002;
|
|
uint256 constant INIT_AMOUNT = 1337 * 1e18;
|
|
uint256 constant EXISTENTIAL = 0;
|
|
|
|
Gatekeeper gatekeeper;
|
|
MockStaking staking;
|
|
|
|
function setUp() public {
|
|
vm.prank(ALICE);
|
|
staking = new MockStaking(EXISTENTIAL);
|
|
|
|
staking.runGhost(bytes32(abi.encodePacked(ALICE)), INIT_AMOUNT);
|
|
gatekeeper = staking.gatekeeper();
|
|
}
|
|
|
|
function test_correctStorageHistoryInitialization() public view {
|
|
address storageHistory = gatekeeper.storageHistory();
|
|
IStorageHistory.DeploymentSnapshot memory snapshot = IStorageHistory(storageHistory).deploymentSnapshot();
|
|
|
|
assertEq(snapshot.deployedAt, 0);
|
|
assertEq(snapshot.amountIn, INIT_AMOUNT);
|
|
assertEq(snapshot.amountOut, 0);
|
|
assertEq(gatekeeper.ghostedSupply(), INIT_AMOUNT);
|
|
}
|
|
|
|
function test_historicalAmountsOnlyIncrease(uint256 ghostAmount, uint64 exodusSession) public {
|
|
vm.assume(ghostAmount > 0 && ghostAmount < INIT_AMOUNT);
|
|
|
|
uint256 amountToGhost = ghostAmount;
|
|
uint256 amountToMaterialize = ghostAmount / 2;
|
|
|
|
bytes32 receiver = bytes32(abi.encodePacked(ALICE));
|
|
address storageHistory = gatekeeper.storageHistory();
|
|
|
|
IStorageHistory.DeploymentSnapshot memory snapshot = IStorageHistory(storageHistory).deploymentSnapshot();
|
|
uint104 amountIn = snapshot.amountIn;
|
|
uint104 amountOut = snapshot.amountOut;
|
|
|
|
if (ghostAmount % 2 == 0) {
|
|
staking.runGhost(receiver, amountToGhost);
|
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
amountIn += uint104(amountToGhost);
|
|
} else {
|
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
uint256 packed = RequestPacking.pack(0, uint64(block.chainid), BOB);
|
|
uint256 previousAmount = staking.materializedAmount(BOB);
|
|
|
|
staking.runMaterialize(exodusSession, amountToMaterialize, packed);
|
|
assertEq(previousAmount + amountToMaterialize, staking.materializedAmount(BOB));
|
|
|
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
amountOut += uint104(amountToMaterialize);
|
|
}
|
|
|
|
IStorageHistory.DeploymentSnapshot memory newSnapshot = IStorageHistory(storageHistory).deploymentSnapshot();
|
|
assertEq(newSnapshot.amountIn, amountIn);
|
|
assertEq(newSnapshot.amountOut, amountOut);
|
|
assertEq(gatekeeper.ghostedSupply(), amountIn - amountOut);
|
|
}
|
|
|
|
function test_inheritanceWorksForHistoricalStorge() public {
|
|
uint256 exodusSession = 69;
|
|
uint256 packed = RequestPacking.pack(0, uint64(block.chainid), BOB);
|
|
staking.runMaterialize(exodusSession, INIT_AMOUNT, packed);
|
|
staking.runGhost(bytes32(abi.encodePacked(ALICE)), INIT_AMOUNT);
|
|
|
|
address prevStorageHistory = gatekeeper.storageHistory();
|
|
IStorageHistory.DeploymentSnapshot memory prevSnapshot = IStorageHistory(prevStorageHistory).deploymentSnapshot();
|
|
|
|
staking.redoGatekeeper(EXISTENTIAL + 1);
|
|
assert(gatekeeper != staking.gatekeeper());
|
|
|
|
address currStorageHistory = gatekeeper.storageHistory();
|
|
IStorageHistory.DeploymentSnapshot memory currSnapshot = IStorageHistory(currStorageHistory).deploymentSnapshot();
|
|
|
|
assertEq(prevSnapshot.amountIn, currSnapshot.amountIn);
|
|
assertEq(prevSnapshot.amountOut, currSnapshot.amountOut);
|
|
assertEq(prevSnapshot.deployedAt, currSnapshot.deployedAt);
|
|
|
|
assert(IStorageHistory(prevStorageHistory).isTransactionExecuted(exodusSession));
|
|
assert(IStorageHistory(currStorageHistory).isTransactionExecuted(exodusSession));
|
|
|
|
assertEq(gatekeeper.existentialDeposit(), EXISTENTIAL);
|
|
assertEq(staking.gatekeeper().existentialDeposit(), EXISTENTIAL + 1);
|
|
}
|
|
}
|