implement linear dynamic gas pricing and update execution buffer
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
de2e49c877
commit
5f01391cb7
@ -22,15 +22,17 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
||||
using GovernancePacking for GovernancePacking.GovernancePayload;
|
||||
|
||||
uint256 public constant BOUNTY_DIVISOR = type(uint32).max;
|
||||
uint256 public constant EXISTENTIAL_DEPOSIT = 500 * 1e12; // 0.005
|
||||
uint256 public constant FULL_GAS_RESTORATION_TIME = 3600; // 1 hour
|
||||
uint256 public constant MAX_ALLOWED_GAS_PRICE = 3e9; // 3 gwei
|
||||
uint256 public constant EXISTENTIAL_DEPOSIT = 500 * 1e12;
|
||||
uint256 public constant GAS_EXECUTION_BUFFER = 33805;
|
||||
uint256 public constant GAS_EXECUTION_BUFFER = 21000 + 5969 + 50955;
|
||||
uint256 public constant REGISTRY_INDEX = 0;
|
||||
|
||||
address public override staking;
|
||||
address public override deployer;
|
||||
address public override storageHistory;
|
||||
|
||||
uint256 private _lastVerificationTime;
|
||||
address private _previousAddress;
|
||||
bool private _initialized;
|
||||
|
||||
@ -109,6 +111,16 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
||||
return (publicKey, state.parity, state.session);
|
||||
}
|
||||
|
||||
function getCurrentGasPrice() public view returns (uint256) {
|
||||
uint256 timePassed = block.timestamp - _lastVerificationTime;
|
||||
|
||||
if (timePassed >= FULL_GAS_RESTORATION_TIME) {
|
||||
return MAX_ALLOWED_GAS_PRICE;
|
||||
}
|
||||
|
||||
return FullMath.mulDiv(MAX_ALLOWED_GAS_PRICE, timePassed, FULL_GAS_RESTORATION_TIME);
|
||||
}
|
||||
|
||||
function ghost(bytes32 receiver, uint256 amount) external override {
|
||||
if (msg.sender != staking) revert NotStaking();
|
||||
if (amount < EXISTENTIAL_DEPOSIT) revert NonExistentAmount();
|
||||
@ -121,25 +133,24 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
||||
bytes calldata call,
|
||||
uint256 rx,
|
||||
uint256 s
|
||||
) external nonReentrant returns (bytes memory) {
|
||||
) external nonReentrant {
|
||||
uint256 gasStart = gasleft();
|
||||
uint256 px = _extractPublicKey(call);
|
||||
|
||||
bool validSignature = Verifier.verifyGhost(call, px, rx, s);
|
||||
if (!validSignature) revert BadSignature();
|
||||
|
||||
(bool success, bytes memory data) = address(this).call(call);
|
||||
(bool success,) = address(this).call(call);
|
||||
if (!success) revert ExecutionReverted();
|
||||
|
||||
uint256 gasPrice = MAX_ALLOWED_GAS_PRICE < tx.gasprice ? MAX_ALLOWED_GAS_PRICE : tx.gasprice;
|
||||
uint256 gasSpent = (gasStart - gasleft() + GAS_EXECUTION_BUFFER) * gasPrice;
|
||||
uint256 currentGasPrice = getCurrentGasPrice();
|
||||
_lastVerificationTime = block.timestamp;
|
||||
|
||||
uint256 gasSpent = (gasStart - gasleft() + GAS_EXECUTION_BUFFER) * currentGasPrice;
|
||||
try IStaking(staking).phantomRefund(msg.sender, gasSpent, REGISTRY_INDEX) {}
|
||||
catch {
|
||||
emit VoluntaryVerification(msg.sender, gasSpent);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function recall(
|
||||
@ -192,7 +203,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
||||
function govern(
|
||||
uint256 exodusSession,
|
||||
uint256 packed,
|
||||
bytes calldata
|
||||
bytes calldata call
|
||||
) external {
|
||||
if (msg.sender != address(this)) revert NotGatekeeper();
|
||||
|
||||
@ -201,7 +212,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
||||
|
||||
StorageHistory(storageHistory).trySetTransactionExecuted(exodusSession);
|
||||
|
||||
(bool success,) = payload.target.call(msg.data[132:]);
|
||||
(bool success,) = payload.target.call(call);
|
||||
if (!success) revert ExecutionReverted();
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +92,64 @@ contract GatekeeperRecallTest is Test {
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function test_gasPriceCorrectDuringRecall() public {
|
||||
vm.startPrank(INITIALIZER);
|
||||
Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper()));
|
||||
gatekeeper.updatePublicKeyMetadata(0, 0xb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de6, 0);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.startPrank(ALICE);
|
||||
uint256 aliceBalance = ftso.balanceOf(ALICE);
|
||||
ftso.approve(address(staking), type(uint256).max);
|
||||
staking.stake(aliceBalance, ALICE, false, true);
|
||||
|
||||
uint256 ghostBalance = ghst.balanceOf(ALICE);
|
||||
staking.ghost(bytes32(abi.encodePacked(ALICE)), ghostBalance);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.warp(block.timestamp + gatekeeper.FULL_GAS_RESTORATION_TIME() * 69);
|
||||
|
||||
uint256 bobBalanceBeforeFirst = ghst.balanceOf(BOB);
|
||||
uint256 priceBeforeFirst = gatekeeper.getCurrentGasPrice();
|
||||
assertEq(priceBeforeFirst, gatekeeper.MAX_ALLOWED_GAS_PRICE());
|
||||
assertEq(ghst.balanceOf(BOB), 0);
|
||||
|
||||
vm.prank(BOB, BOB);
|
||||
gatekeeper.verify(
|
||||
hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000017508f1956a800000000000000000000000000000000000000000020000000000007a6980000000",
|
||||
0x883302783b7f3d253d5bdeb17f39117641acdf061bf3fe457cb505df6b17dfc1,
|
||||
0x8c3fc03b5cb738777ceec396ee8647f782d6670992f8f973de2dfc83379978d5
|
||||
);
|
||||
|
||||
uint256 bobBalanceAfterFirst = ghst.balanceOf(BOB);
|
||||
assertGt(bobBalanceAfterFirst, bobBalanceBeforeFirst);
|
||||
assertEq(gatekeeper.getCurrentGasPrice(), 0);
|
||||
|
||||
vm.prank(BOB, BOB);
|
||||
gatekeeper.verify(
|
||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000120000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000042b7ce50000000000000000000000000000000000000000000000000000000000",
|
||||
0xf1f4d62d27c3d0388b2298b621b23cd5791e1b97d4423ffc16b14e81ff0df97c,
|
||||
0xdbeed3eb94a829710147595c1b10f2ac6ec761c9721d8cc4711842c212ac517e
|
||||
);
|
||||
|
||||
assertEq(ghst.balanceOf(BOB), bobBalanceAfterFirst);
|
||||
assertEq(gatekeeper.getCurrentGasPrice(), 0);
|
||||
|
||||
vm.warp(block.timestamp + gatekeeper.FULL_GAS_RESTORATION_TIME() / 2);
|
||||
uint256 gasPriceRestored = gatekeeper.getCurrentGasPrice();
|
||||
assertEq(gasPriceRestored, gatekeeper.MAX_ALLOWED_GAS_PRICE() / 2);
|
||||
|
||||
vm.prank(BOB, BOB);
|
||||
gatekeeper.verify(
|
||||
hex"31371426000000000000000000000000000000000000000000000000000000000000000d0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064e4e33ef800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
||||
0x0716f763060cfd52339544a203d0e156a42370b0e22d78ea9bf8766b0b66682b,
|
||||
0xc2da93948f869c5102992bd1cbd70ef5f821ff522305c69d113faf2e89570ce7
|
||||
);
|
||||
|
||||
assertGt(ghst.balanceOf(BOB), bobBalanceAfterFirst);
|
||||
assertEq(gatekeeper.getCurrentGasPrice(), 0);
|
||||
}
|
||||
|
||||
function test_recallChainWorks() public {
|
||||
vm.startPrank(INITIALIZER);
|
||||
Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper()));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user